You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ki...@apache.org on 2013/09/12 06:29:48 UTC
svn commit: r1522355 [1/5] - in /commons/proper/functor/trunk:
core/src/main/java/org/apache/commons/functor/adapter/
core/src/main/java/org/apache/commons/functor/core/algorithm/
core/src/main/java/org/apache/commons/functor/generator/ core/src/main/j...
Author: kinow
Date: Thu Sep 12 04:29:46 2013
New Revision: 1522355
URL: http://svn.apache.org/r1522355
Log:
[FUNCTOR-14] Merge branch generators-FUNCTOR-14. Adding the loop and range packages, and simplifying the BaseGenerator type.
Added:
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/GenerateUntil.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/GenerateWhile.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/IteratorToGeneratorAdapter.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/LoopGenerator.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/TransformedGenerator.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/UntilGenerate.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/WhileGenerate.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/package-info.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/BoundType.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/CharacterRange.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/DoubleRange.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/Endpoint.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/FloatRange.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/IntegerRange.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/LongRange.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/NumericRange.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/Range.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/Ranges.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/package-info.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/generator/loop/
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/generator/loop/TestGenerateUntil.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/generator/loop/TestGenerateWhile.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/generator/loop/TestIteratorToGeneratorAdapter.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/generator/loop/TestLoopGenerator.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/generator/loop/TestTransformedGenerator.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/generator/loop/TestUntilGenerate.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/generator/loop/TestWhileGenerate.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/range/
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/range/TestCharacterRange.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/range/TestDoubleRange.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/range/TestEndpoint.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/range/TestFloatRange.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/range/TestIntegerRange.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/range/TestLongRange.java
Removed:
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/GenerateUntil.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/GenerateWhile.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/IteratorToGeneratorAdapter.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/TransformedGenerator.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/UntilGenerate.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/WhileGenerate.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/util/IntegerRange.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/util/LongRange.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/generator/TestGenerateUntil.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/generator/TestGenerateWhile.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/generator/TestIteratorToGeneratorAdapter.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/generator/TestTransformedGenerator.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/generator/TestUntilGenerate.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/generator/TestWhileGenerate.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/generator/util/TestIntegerRange.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/generator/util/TestLongRange.java
Modified:
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/adapter/FullyBoundNullaryPredicate.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/adapter/FullyBoundNullaryProcedure.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/core/algorithm/IndexOfInGenerator.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/BaseGenerator.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/FilteredGenerator.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/Generator.java
commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/util/EachElement.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/TestAlgorithms.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/core/algorithm/TestFindWithinGenerator.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/core/algorithm/TestFoldLeft.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/core/algorithm/TestFoldRight.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/core/algorithm/TestGeneratorContains.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/core/algorithm/TestIndexOfInGenerator.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/example/QuicksortExample.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/example/kata/two/TestBinaryChop.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/example/lines/Lines.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/example/lines/TestLines.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/example/map/FixedSizeMap.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/generator/TestBaseGenerator.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/generator/TestFilteredGenerator.java
commons/proper/functor/trunk/core/src/test/java/org/apache/commons/functor/generator/util/TestEachElement.java
commons/proper/functor/trunk/src/changes/changes.xml
commons/proper/functor/trunk/src/site/xdoc/examples.xml
Modified: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/adapter/FullyBoundNullaryPredicate.java
URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/adapter/FullyBoundNullaryPredicate.java?rev=1522355&r1=1522354&r2=1522355&view=diff
==============================================================================
--- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/adapter/FullyBoundNullaryPredicate.java (original)
+++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/adapter/FullyBoundNullaryPredicate.java Thu Sep 12 04:29:46 2013
@@ -24,7 +24,7 @@ import org.apache.commons.lang3.Validate
/**
* Adapts a
- * {@link BinaryNullaryPredicate BinaryNullaryPredicate}
+ * {@link BinaryPredicate BinaryPredicate}
* to the
* {@link org.apache.commons.functor.NullaryPredicate NullaryPredicate} interface
* using a constant left-side argument.
Modified: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/adapter/FullyBoundNullaryProcedure.java
URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/adapter/FullyBoundNullaryProcedure.java?rev=1522355&r1=1522354&r2=1522355&view=diff
==============================================================================
--- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/adapter/FullyBoundNullaryProcedure.java (original)
+++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/adapter/FullyBoundNullaryProcedure.java Thu Sep 12 04:29:46 2013
@@ -24,7 +24,7 @@ import org.apache.commons.lang3.Validate
/**
* Adapts a
- * {@link BinaryNullaryProcedure BinaryNullaryProcedure}
+ * {@link BinaryProcedure BinaryProcedure}
* to the
* {@link NullaryProcedure NullaryProcedure} interface
* using a constant left-side argument.
@@ -43,7 +43,7 @@ public final class FullyBoundNullaryProc
* serialVersionUID declaration.
*/
private static final long serialVersionUID = -904891610081737737L;
- /** The {@link BinaryNullaryProcedure BinaryNullaryProcedure} I'm wrapping. */
+ /** The {@link BinaryProcedure BinaryProcedure} I'm wrapping. */
private final BinaryProcedure<Object, Object> procedure;
/** The left parameter to pass to {@code procedure}. */
private final Object left;
Modified: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/core/algorithm/IndexOfInGenerator.java
URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/core/algorithm/IndexOfInGenerator.java?rev=1522355&r1=1522354&r2=1522355&view=diff
==============================================================================
--- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/core/algorithm/IndexOfInGenerator.java (original)
+++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/core/algorithm/IndexOfInGenerator.java Thu Sep 12 04:29:46 2013
@@ -21,20 +21,21 @@ import java.io.Serializable;
import org.apache.commons.functor.BinaryFunction;
import org.apache.commons.functor.Predicate;
import org.apache.commons.functor.Procedure;
-import org.apache.commons.functor.generator.Generator;
+import org.apache.commons.functor.generator.loop.LoopGenerator;
/**
- * Return the index of the first Object in a {@link Generator} matching a {@link Predicate}, or -1 if not found.
+ * Return the index of the first Object in a {@link LoopGenerator} matching a
+ * {@link Predicate}, or -1 if not found.
*
* @param <T> the procedure argument types
* @version $Revision$ $Date$
*/
public final class IndexOfInGenerator<T>
- implements BinaryFunction<Generator<? extends T>, Predicate<? super T>, Number>, Serializable {
+ implements BinaryFunction<LoopGenerator<? extends T>, Predicate<? super T>, Number>, Serializable {
/**
* serialVersionUID declaration.
*/
- private static final long serialVersionUID = -11365986575536471L;
+ private static final long serialVersionUID = -2672603607256310480L;
/**
* A static {@code IndexOfInGenerator} instance reference.
*/
@@ -49,7 +50,7 @@ public final class IndexOfInGenerator<T>
/**
* The wrapped generator.
*/
- private final Generator<? extends T> generator;
+ private final LoopGenerator<? extends T> generator;
/**
* The wrapped predicate.
*/
@@ -70,7 +71,7 @@ public final class IndexOfInGenerator<T>
* @param generator The wrapped generator
* @param pred The wrapped predicate
*/
- IndexProcedure(Generator<? extends T> generator, Predicate<? super T> pred) {
+ IndexProcedure(LoopGenerator<? extends T> generator, Predicate<? super T> pred) {
this.generator = generator;
this.pred = pred;
}
@@ -89,10 +90,10 @@ public final class IndexOfInGenerator<T>
/**
* {@inheritDoc}
- * @param left Generator
+ * @param left LoopGenerator
* @param right Predicate
*/
- public Number evaluate(Generator<? extends T> left, Predicate<? super T> right) {
+ public Number evaluate(LoopGenerator<? extends T> left, Predicate<? super T> right) {
IndexProcedure<T> findProcedure = new IndexProcedure<T>(left, right);
left.run(findProcedure);
return Long.valueOf(findProcedure.index);
Modified: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/BaseGenerator.java
URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/BaseGenerator.java?rev=1522355&r1=1522354&r2=1522355&view=diff
==============================================================================
--- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/BaseGenerator.java (original)
+++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/BaseGenerator.java Thu Sep 12 04:29:46 2013
@@ -29,52 +29,9 @@ import org.apache.commons.functor.genera
*/
public abstract class BaseGenerator<E> implements Generator<E> {
- /** A generator can wrap another generator. */
- private final Generator<?> wrappedGenerator;
-
- /** Set to true when the generator is {@link #stop stopped}. */
- private boolean stopped = false;
-
/** Create a new generator. */
public BaseGenerator() {
- this(null);
- }
-
- /**
- * A generator can wrap another generator. When wrapping generators you
- * should use probably this constructor since doing so will cause the
- * {@link #stop} method to stop the wrapped generator as well.
- * @param generator Generator to wrap
- */
- public BaseGenerator(Generator<?> generator) {
- this.wrappedGenerator = generator;
- }
-
- /**
- * Get the generator that is being wrapped.
- * @return Generator
- */
- protected Generator<?> getWrappedGenerator() {
- return wrappedGenerator;
- }
-
- /**
- * {@inheritDoc}
- * Stop the generator. Will stop the wrapped generator if one was set.
- */
- public void stop() {
- if (wrappedGenerator != null) {
- wrappedGenerator.stop();
- }
- stopped = true;
- }
-
- /**
- * {@inheritDoc}
- * Check if the generator is stopped.
- */
- public boolean isStopped() {
- return stopped;
+ super();
}
/**
Modified: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/FilteredGenerator.java
URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/FilteredGenerator.java?rev=1522355&r1=1522354&r2=1522355&view=diff
==============================================================================
--- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/FilteredGenerator.java (original)
+++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/FilteredGenerator.java Thu Sep 12 04:29:46 2013
@@ -31,7 +31,12 @@ import org.apache.commons.lang3.Validate
public class FilteredGenerator<E> extends BaseGenerator<E> {
/**
- * The wrapped generator.
+ * A generator can wrap another generator.
+ * */
+ private Generator<? extends E> wrappedGenerator;
+
+ /**
+ * The predicate used to filter.
*/
private final Predicate<? super E> pred;
@@ -41,7 +46,7 @@ public class FilteredGenerator<E> extend
* @param pred filtering Predicate
*/
public FilteredGenerator(Generator<? extends E> wrapped, Predicate<? super E> pred) {
- super(Validate.notNull(wrapped, "Generator argument was null"));
+ this.wrappedGenerator = Validate.notNull(wrapped, "Generator argument was null");
this.pred = Validate.notNull(pred, "Predicate argument was null");
}
@@ -53,12 +58,11 @@ public class FilteredGenerator<E> extend
}
/**
- * {@inheritDoc}
+ * Get the generator that is being wrapped.
+ * @return Generator
*/
- @SuppressWarnings("unchecked")
- @Override
protected Generator<? extends E> getWrappedGenerator() {
- return (Generator<? extends E>) super.getWrappedGenerator();
+ return this.wrappedGenerator;
}
/**
Modified: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/Generator.java
URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/Generator.java?rev=1522355&r1=1522354&r2=1522355&view=diff
==============================================================================
--- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/Generator.java (original)
+++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/Generator.java Thu Sep 12 04:29:46 2013
@@ -33,21 +33,10 @@ public interface Generator<E> {
void run(Procedure<? super E> proc);
/**
- * Stop the generator. Will stop the wrapped generator if one was set.
- */
- void stop();
-
- /**
- * Check if the generator is stopped.
- * @return true if stopped
- */
- boolean isStopped();
-
- /**
* Transforms this generator using the passed in
* transformer. An example transformer might turn the contents of the
* generator into a {@link Collection} of elements.
- * @param <Z> the returned value type of the input {@link Function}.
+ * @param <Z> the returned value type of the input {@link Function}
* @param transformer Function to apply to this
* @return transformation result
*/
@@ -55,7 +44,7 @@ public interface Generator<E> {
/**
* Same as to(new CollectionTransformer(collection)).
- * @param <C> the collection type
+ * @param <C> the returned collection type
* @param collection Collection to which my elements should be added
* @return <code>collection</code>
*/
Added: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/GenerateUntil.java
URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/GenerateUntil.java?rev=1522355&view=auto
==============================================================================
--- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/GenerateUntil.java (added)
+++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/GenerateUntil.java Thu Sep 12 04:29:46 2013
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.functor.generator.loop;
+
+import org.apache.commons.functor.Predicate;
+import org.apache.commons.functor.Procedure;
+import org.apache.commons.functor.generator.Generator;
+import org.apache.commons.lang3.Validate;
+
+/**
+ * Wrap another {@link Generator} such that {@link #run(Procedure)} terminates once
+ * a condition has been satisfied (test after).
+ *
+ * @param <E> the type of elements held in this generator.
+ * @version $Revision: 1508677 $ $Date: 2013-07-30 19:48:02 -0300 (Tue, 30 Jul 2013) $
+ */
+public class GenerateUntil<E> extends LoopGenerator<E> {
+
+ /**
+ * The condition has to verified in order to execute the generation.
+ */
+ private final Predicate<? super E> test;
+
+ /**
+ * Create a new GenerateUntil.
+ * @param wrapped {@link Generator}
+ * @param test {@link Predicate}
+ */
+ public GenerateUntil(Generator<? extends E> wrapped, Predicate<? super E> test) {
+ super(Validate.notNull(wrapped, "Generator argument was null"));
+ this.test = Validate.notNull(test, "Predicate argument was null");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void run(final Procedure<? super E> proc) {
+ getWrappedGenerator().run(new Procedure<E>() {
+ public void run(E obj) {
+ proc.run(obj);
+ if (test.test(obj)) {
+ GenerateUntil.this.stop();
+ }
+ }
+ });
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof GenerateUntil<?>)) {
+ return false;
+ }
+ GenerateUntil<?> other = (GenerateUntil<?>) obj;
+ return other.getWrappedGenerator().equals(getWrappedGenerator()) && other.test.equals(test);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ int result = "GenerateUntil".hashCode();
+ result <<= 2;
+ Generator<?> gen = getWrappedGenerator();
+ result ^= gen.hashCode();
+ result <<= 2;
+ result ^= test.hashCode();
+ return result;
+ }
+}
Added: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/GenerateWhile.java
URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/GenerateWhile.java?rev=1522355&view=auto
==============================================================================
--- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/GenerateWhile.java (added)
+++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/GenerateWhile.java Thu Sep 12 04:29:46 2013
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.functor.generator.loop;
+
+import org.apache.commons.functor.Predicate;
+import org.apache.commons.functor.Procedure;
+import org.apache.commons.functor.generator.Generator;
+import org.apache.commons.lang3.Validate;
+
+/**
+ * Wrap another {@link Generator} such that {@link #run(Procedure)} continues
+ * as long as a condition is true (test after).
+ *
+ * @param <E> the type of elements held in this generator.
+ * @version $Revision: 1508677 $ $Date: 2013-07-30 19:48:02 -0300 (Tue, 30 Jul 2013) $
+ */
+public class GenerateWhile<E> extends LoopGenerator<E> {
+
+ /**
+ * The condition has to verified in order to execute the generation.
+ */
+ private final Predicate<? super E> test;
+
+ /**
+ * Create a new GenerateWhile.
+ * @param wrapped {@link Generator}
+ * @param test {@link Predicate}
+ */
+ public GenerateWhile(Generator<? extends E> wrapped, Predicate<? super E> test) {
+ super(Validate.notNull(wrapped, "Generator argument was null"));
+ this.test = Validate.notNull(test, "Predicate argument was null");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void run(final Procedure<? super E> proc) {
+ getWrappedGenerator().run(new Procedure<E>() {
+ public void run(E obj) {
+ proc.run(obj);
+ if (!test.test(obj)) {
+ GenerateWhile.this.stop();
+ }
+ }
+ });
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof GenerateWhile<?>)) {
+ return false;
+ }
+ GenerateWhile<?> other = (GenerateWhile<?>) obj;
+ return other.getWrappedGenerator().equals(getWrappedGenerator()) && other.test.equals(test);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ int result = "GenerateWhile".hashCode();
+ result <<= 2;
+ Generator<?> gen = getWrappedGenerator();
+ result ^= gen.hashCode();
+ result <<= 2;
+ result ^= test.hashCode();
+ return result;
+ }
+}
Added: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/IteratorToGeneratorAdapter.java
URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/IteratorToGeneratorAdapter.java?rev=1522355&view=auto
==============================================================================
--- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/IteratorToGeneratorAdapter.java (added)
+++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/IteratorToGeneratorAdapter.java Thu Sep 12 04:29:46 2013
@@ -0,0 +1,109 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.functor.generator.loop;
+
+import java.util.Iterator;
+
+import org.apache.commons.functor.Procedure;
+import org.apache.commons.lang3.Validate;
+
+/**
+ * Adapts an {@link Iterator} to the {@link LoopGenerator} interface.
+ *
+ * @param <E> the type of elements held in this generator.
+ * @since 1.0
+ * @version $Revision: 1508677 $ $Date: 2013-07-30 19:48:02 -0300 (Tue, 30 Jul 2013) $
+ */
+public final class IteratorToGeneratorAdapter<E> extends LoopGenerator<E> {
+ // instance variables
+ //-----------------------------------------------------
+
+ /**
+ * The adapted iterator.
+ */
+ private final Iterator<? extends E> iter;
+
+ // constructors
+ //-----------------------------------------------------
+ /**
+ * Create a new IteratorToGeneratorAdapter.
+ * @param iter Iterator to adapt
+ */
+ public IteratorToGeneratorAdapter(Iterator<? extends E> iter) {
+ this.iter = Validate.notNull(iter, "Iterator argument was null");
+ }
+
+ // instance methods
+ //-----------------------------------------------------
+ /**
+ * {@inheritDoc}
+ */
+ public void run(Procedure<? super E> proc) {
+ while (iter.hasNext()) {
+ proc.run(iter.next());
+ if (isStopped()) {
+ break;
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof IteratorToGeneratorAdapter<?>)) {
+ return false;
+ }
+ IteratorToGeneratorAdapter<?> that = (IteratorToGeneratorAdapter<?>) obj;
+ return this.iter.equals(that.iter);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ int hash = "IteratorToGeneratorAdapater".hashCode();
+ hash <<= 2;
+ hash ^= iter.hashCode();
+ return hash;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return "IteratorToGeneratorAdapter<" + iter + ">";
+ }
+
+ // static methods
+ //-----------------------------------------------------
+ /**
+ * Adapt an Iterator to the Generator interface.
+ *
+ * @param <E> the type of elements held in this generator.
+ * @param iter to adapt
+ * @return IteratorToGeneratorAdapter
+ */
+ public static <E> IteratorToGeneratorAdapter<E> adapt(Iterator<? extends E> iter) {
+ return null == iter ? null : new IteratorToGeneratorAdapter<E>(iter);
+ }
+
+}
Added: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/LoopGenerator.java
URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/LoopGenerator.java?rev=1522355&view=auto
==============================================================================
--- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/LoopGenerator.java (added)
+++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/LoopGenerator.java Thu Sep 12 04:29:46 2013
@@ -0,0 +1,78 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.functor.generator.loop;
+
+import org.apache.commons.functor.generator.BaseGenerator;
+import org.apache.commons.functor.generator.Generator;
+
+/**
+ * Base class for generators that control execution flow, and may need to
+ * stop the generation.
+ *
+ * @param <E> the type of elements held in this generator.
+ * @since 1.0
+ * @version $Revision$ $Date$
+ */
+public abstract class LoopGenerator<E> extends BaseGenerator<E> {
+
+ /** A generator can wrap another generator. */
+ private final Generator<? extends E> wrappedGenerator;
+
+ /** Set to true when the generator is {@link #stop stopped}. */
+ private boolean stopped = false;
+
+ /** Create a new generator. */
+ public LoopGenerator() {
+ this(null);
+ }
+
+ /**
+ * A generator can wrap another generator. When wrapping generators you
+ * should use probably this constructor since doing so will cause the
+ * {@link #stop} method to stop the wrapped generator as well.
+ * @param generator Generator to wrap
+ */
+ public LoopGenerator(Generator<? extends E> generator) {
+ this.wrappedGenerator = generator;
+ }
+
+ /**
+ * Get the generator that is being wrapped.
+ * @return Generator
+ */
+ protected Generator<? extends E> getWrappedGenerator() {
+ return wrappedGenerator;
+ }
+
+ /**
+ * Stop the generator. Will stop the wrapped generator if one was set.
+ */
+ public void stop() {
+ if (wrappedGenerator != null && wrappedGenerator instanceof LoopGenerator<?>) {
+ ((LoopGenerator<?>) wrappedGenerator).stop();
+ }
+ stopped = true;
+ }
+
+ /**
+ * Check if the generator is stopped.
+ * @return <code>true</code> if the generator is stopped, <code>false</code>
+ * otherwise
+ */
+ public boolean isStopped() {
+ return stopped;
+ }
+
+}
Added: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/TransformedGenerator.java
URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/TransformedGenerator.java?rev=1522355&view=auto
==============================================================================
--- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/TransformedGenerator.java (added)
+++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/TransformedGenerator.java Thu Sep 12 04:29:46 2013
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.functor.generator.loop;
+
+import org.apache.commons.functor.Function;
+import org.apache.commons.functor.Procedure;
+import org.apache.commons.functor.generator.Generator;
+import org.apache.commons.lang3.Validate;
+
+/**
+ * Generator that transforms the elements of another Generator.
+ *
+ * @param <I> the type of elements held in the wrapped generator.
+ * @param <E> the type of elements held in this generator.
+ * @version $Revision: 1508677 $ $Date: 2013-07-30 19:48:02 -0300 (Tue, 30 Jul 2013) $
+ */
+public class TransformedGenerator<I, E> extends LoopGenerator<E> {
+
+ /**
+ * The Function to apply to each element.
+ */
+ private final Function<? super I, ? extends E> func;
+
+ /**
+ * Create a new TransformedGenerator.
+ * @param wrapped Generator to transform
+ * @param func Function to apply to each element
+ */
+ // Even though we are passing a Generator<? extends I> to super, and using
+ // it in TransformedGenerator#run, what gets actually passed to the Procedure
+ // is a <? extends E>, returned by func.
+ @SuppressWarnings("unchecked")
+ public TransformedGenerator(Generator<? extends I> wrapped, Function<? super I, ? extends E> func) {
+ super((Generator<? extends E>) Validate.notNull(wrapped, "Generator argument was null"));
+ this.func = Validate.notNull(func, "Function argument was null");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ // See comment above in the public constructor
+ @SuppressWarnings("unchecked")
+ public void run(final Procedure<? super E> proc) {
+ ((Generator<? extends I>) getWrappedGenerator()).run(new Procedure<I>() {
+ public void run(I obj) {
+ proc.run(func.evaluate(obj));
+ }
+ });
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof TransformedGenerator<?, ?>)) {
+ return false;
+ }
+ TransformedGenerator<?, ?> other = (TransformedGenerator<?, ?>) obj;
+ return other.getWrappedGenerator().equals(getWrappedGenerator()) && other.func == func;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ int result = "TransformedGenerator".hashCode();
+ result <<= 2;
+ Generator<?> gen = getWrappedGenerator();
+ result ^= gen.hashCode();
+ result <<= 2;
+ result ^= func.hashCode();
+ return result;
+ }
+}
Added: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/UntilGenerate.java
URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/UntilGenerate.java?rev=1522355&view=auto
==============================================================================
--- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/UntilGenerate.java (added)
+++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/UntilGenerate.java Thu Sep 12 04:29:46 2013
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.functor.generator.loop;
+
+import org.apache.commons.functor.Predicate;
+import org.apache.commons.functor.Procedure;
+import org.apache.commons.functor.generator.Generator;
+import org.apache.commons.lang3.Validate;
+
+/**
+ * Wrap another {@link Generator} such that {@link #run(Procedure)} terminates once
+ * a condition has been satisfied.
+ *
+ * @param <E> the type of elements held in this generator.
+ * @version $Revision: 1508677 $ $Date: 2013-07-30 19:48:02 -0300 (Tue, 30 Jul 2013) $
+ */
+public class UntilGenerate<E> extends LoopGenerator<E> {
+
+ /**
+ * The condition has to verified in order to execute the generation.
+ */
+ private final Predicate<? super E> test;
+
+ /**
+ * Create a new UntilGenerate.
+ * @param wrapped {@link Generator}
+ * @param test {@link Predicate}
+ */
+ public UntilGenerate(Predicate<? super E> test, Generator<? extends E> wrapped) {
+ super(Validate.notNull(wrapped, "Generator argument was null"));
+ this.test = Validate.notNull(test, "Predicate argument was null");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void run(final Procedure<? super E> proc) {
+ getWrappedGenerator().run(new Procedure<E>() {
+ public void run(E obj) {
+ if (test.test(obj)) {
+ UntilGenerate.this.stop();
+ } else {
+ proc.run(obj);
+ }
+ }
+ });
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof UntilGenerate<?>)) {
+ return false;
+ }
+ UntilGenerate<?> other = (UntilGenerate<?>) obj;
+ return other.getWrappedGenerator().equals(getWrappedGenerator()) && other.test.equals(test);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ int result = "UntilGenerate".hashCode();
+ result <<= 2;
+ Generator<?> gen = getWrappedGenerator();
+ result ^= gen.hashCode();
+ result <<= 2;
+ result ^= test.hashCode();
+ return result;
+ }
+}
Added: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/WhileGenerate.java
URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/WhileGenerate.java?rev=1522355&view=auto
==============================================================================
--- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/WhileGenerate.java (added)
+++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/WhileGenerate.java Thu Sep 12 04:29:46 2013
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.functor.generator.loop;
+
+import org.apache.commons.functor.Predicate;
+import org.apache.commons.functor.Procedure;
+import org.apache.commons.functor.generator.Generator;
+import org.apache.commons.lang3.Validate;
+
+/**
+ * Wrap another {@link Generator} such that {@link #run(Procedure)} continues
+ * as long as a condition is true (test before).
+ *
+ * @param <E> the type of elements held in this generator.
+ * @version $Revision: 1508677 $ $Date: 2013-07-30 19:48:02 -0300 (Tue, 30 Jul 2013) $
+ */
+public class WhileGenerate<E> extends LoopGenerator<E> {
+
+ /**
+ * The condition has to verified in order to execute the generation.
+ */
+ private final Predicate<? super E> test;
+
+ /**
+ * Create a new WhileGenerate.
+ * @param test {@link Predicate}
+ * @param wrapped {@link Generator}
+ */
+ public WhileGenerate(Predicate<? super E> test, Generator<? extends E> wrapped) {
+ super(Validate.notNull(wrapped, "Generator argument was null"));
+ this.test = Validate.notNull(test, "Predicate argument was null");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void run(final Procedure<? super E> proc) {
+ getWrappedGenerator().run(new Procedure<E>() {
+ public void run(E obj) {
+ if (!test.test(obj)) {
+ WhileGenerate.this.stop();
+ } else {
+ proc.run(obj);
+ }
+ }
+ });
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof WhileGenerate<?>)) {
+ return false;
+ }
+ WhileGenerate<?> other = (WhileGenerate<?>) obj;
+ return other.getWrappedGenerator().equals(getWrappedGenerator()) && other.test.equals(test);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ int result = "WhileGenerate".hashCode();
+ result <<= 2;
+ Generator<?> gen = getWrappedGenerator();
+ result ^= gen.hashCode();
+ result <<= 2;
+ result ^= test.hashCode();
+ return result;
+ }
+}
Added: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/package-info.java
URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/package-info.java?rev=1522355&view=auto
==============================================================================
--- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/package-info.java (added)
+++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/loop/package-info.java Thu Sep 12 04:29:46 2013
@@ -0,0 +1,19 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * <p>
+ * Contains code related to Generators that control execution flow.
+ * </p>
+ */
+package org.apache.commons.functor.generator.loop;
Modified: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/util/EachElement.java
URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/util/EachElement.java?rev=1522355&r1=1522354&r2=1522355&view=diff
==============================================================================
--- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/util/EachElement.java (original)
+++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/generator/util/EachElement.java Thu Sep 12 04:29:46 2013
@@ -19,7 +19,7 @@ import java.util.Iterator;
import java.util.Map;
import org.apache.commons.functor.generator.Generator;
-import org.apache.commons.functor.generator.IteratorToGeneratorAdapter;
+import org.apache.commons.functor.generator.loop.IteratorToGeneratorAdapter;
/**
* Generator factory for each element of a "collection".
Added: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/BoundType.java
URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/BoundType.java?rev=1522355&view=auto
==============================================================================
--- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/BoundType.java (added)
+++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/BoundType.java Thu Sep 12 04:29:46 2013
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.functor.range;
+
+/**
+ * Determine the bound type of a range.
+ *
+ * @see org.apache.commons.functor.range.Range
+ * @see org.apache.commons.functor.range.Endpoint
+ * @since 1.0
+ * @version $Revision$ $Date$
+ */
+public enum BoundType {
+ // values
+ // ---------------------------------------------------------------
+ /**
+ * Represents an <b>open</b> bound, which value <b>is not</b> included in
+ * the range.
+ */
+ OPEN,
+ /**
+ * Represents a <b>closed</b> bound, which value <b>is included</b> in the
+ * range.
+ */
+ CLOSED;
+
+}
Added: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/CharacterRange.java
URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/CharacterRange.java?rev=1522355&view=auto
==============================================================================
--- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/CharacterRange.java (added)
+++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/CharacterRange.java Thu Sep 12 04:29:46 2013
@@ -0,0 +1,349 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.functor.range;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.apache.commons.functor.BinaryFunction;
+import org.apache.commons.lang3.Validate;
+
+/**
+ * A generator for a range of characters.
+ *
+ * @since 1.0
+ * @version $Revision$ $Date$
+ */
+public final class CharacterRange implements Range<Character, Integer> {
+
+ // attributes
+ // ---------------------------------------------------------------
+ /**
+ * Default left bound type.
+ */
+ public static final BoundType DEFAULT_LEFT_BOUND_TYPE = BoundType.CLOSED;
+
+ /**
+ * Default right bound type.
+ */
+ public static final BoundType DEFAULT_RIGHT_BOUND_TYPE = BoundType.CLOSED;
+
+ /**
+ * Left limit.
+ */
+ private final Endpoint<Character> leftEndpoint;
+
+ /**
+ * Right limit.
+ */
+ private final Endpoint<Character> rightEndpoint;
+
+ /**
+ * Increment step.
+ */
+ private final int step;
+
+ /**
+ * Current value.
+ */
+ private char currentValue;
+
+ /**
+ * Calculate default step.
+ */
+ public static final BinaryFunction<Character, Character, Integer> DEFAULT_STEP
+ = new BinaryFunction<Character, Character, Integer>() {
+
+ public Integer evaluate(Character left, Character right) {
+ return left > right ? -1 : 1;
+ }
+ };
+
+ // constructors
+ // ---------------------------------------------------------------
+ /**
+ * Create a new CharacterRange.
+ *
+ * @param from start
+ * @param to end
+ */
+ public CharacterRange(char from, char to) {
+ this(from, to, DEFAULT_STEP.evaluate(from, to).intValue());
+ }
+
+ /**
+ * Create a new CharacterRange.
+ *
+ * @param from start
+ * @param to end
+ * @param step increment
+ */
+ public CharacterRange(char from, char to, int step) {
+ this(from, BoundType.CLOSED, to, BoundType.CLOSED, step);
+ }
+
+ /**
+ * Create a new CharacterRange.
+ *
+ * @param from start
+ * @param to end
+ */
+ public CharacterRange(Endpoint<Character> from, Endpoint<Character> to) {
+ this(from.getValue(), from.getBoundType(), to.getValue(), to.getBoundType(),
+ DEFAULT_STEP.evaluate(from.getValue(), to.getValue()));
+ }
+
+ /**
+ * Create a new CharacterRange.
+ *
+ * @param from start
+ * @param to end
+ * @param step increment
+ */
+ public CharacterRange(Endpoint<Character> from, Endpoint<Character> to, int step) {
+ this(from.getValue(), from.getBoundType(), to.getValue(), to.getBoundType(), step);
+ }
+
+ /**
+ * Create a new CharacterRange.
+ *
+ * @param from start
+ * @param leftBoundType type of left bound
+ * @param to end
+ * @param rightBoundType type of right bound
+ */
+ public CharacterRange(char from, BoundType leftBoundType, char to,
+ BoundType rightBoundType) {
+ this(from, leftBoundType, to, rightBoundType, DEFAULT_STEP.evaluate(from, to));
+ }
+
+ /**
+ * Create a new CharacterRange.
+ *
+ * @param from start
+ * @param leftBoundType type of left bound
+ * @param to end
+ * @param rightBoundType type of right bound
+ * @param step increment
+ */
+ public CharacterRange(char from, BoundType leftBoundType, char to,
+ BoundType rightBoundType, int step) {
+ this.leftEndpoint = Validate
+ .notNull(new Endpoint<Character>(from, leftBoundType),
+ "Left Endpoint argument must not be null");
+ this.rightEndpoint = Validate
+ .notNull(new Endpoint<Character>(to, rightBoundType),
+ "Right Endpoint argument must not be null");
+ this.step = step;
+ if (from != to && Integer.signum(step) != Integer.signum(to - from)) {
+ throw new IllegalArgumentException("Will never reach " + to
+ + " from " + from
+ + " using step " + step);
+ }
+ if (this.leftEndpoint.getBoundType() == BoundType.CLOSED) {
+ this.currentValue = this.leftEndpoint.getValue();
+ } else {
+ this.currentValue = (char) (this.leftEndpoint.getValue() + this.step);
+ }
+ }
+ // range methods
+ // ---------------------------------------------------------------
+ /**
+ * {@inheritDoc}
+ */
+ public Endpoint<Character> getLeftEndpoint() {
+ return this.leftEndpoint;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Endpoint<Character> getRightEndpoint() {
+ return this.rightEndpoint;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Integer getStep() {
+ return this.step;
+ }
+
+ // iterable, iterator methods
+ // ---------------------------------------------------------------
+ /**
+ * {@inheritDoc}
+ */
+ public boolean hasNext() {
+ final int to = this.rightEndpoint.getValue();
+ if (step < 0) {
+ if (this.rightEndpoint.getBoundType() == BoundType.CLOSED) {
+ return this.currentValue >= to;
+ } else {
+ return this.currentValue > to;
+ }
+ } else {
+ if (this.rightEndpoint.getBoundType() == BoundType.CLOSED) {
+ return this.currentValue <= to;
+ } else {
+ return this.currentValue < to;
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Character next() {
+ final int step = this.getStep();
+ final char r = this.currentValue;
+ this.currentValue += step;
+ return r;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Iterator<Character> iterator() {
+ return this;
+ }
+
+ // object methods
+ // ---------------------------------------------------------------
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return "CharacterRange<" + this.leftEndpoint.toLeftString() + ", "
+ + this.rightEndpoint.toRightString() + ", " + step + ">";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof CharacterRange)) {
+ return false;
+ }
+ CharacterRange that = (CharacterRange) obj;
+ return this.leftEndpoint.equals(that.leftEndpoint)
+ && this.rightEndpoint.equals(that.rightEndpoint)
+ && this.step == that.step;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ int hash = "CharacterRange".hashCode();
+ hash <<= 2;
+ hash ^= this.leftEndpoint.getValue();
+ hash <<= 2;
+ hash ^= this.rightEndpoint.getValue();
+ hash <<= 2;
+ hash ^= this.step;
+ return hash;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isEmpty() {
+ double leftValue = this.getLeftEndpoint().getValue().charValue();
+ double rightValue = this.getRightEndpoint().getValue().charValue();
+ boolean closedLeft = this.getLeftEndpoint().getBoundType() == BoundType.CLOSED;
+ boolean closedRight = this.getRightEndpoint().getBoundType() == BoundType.CLOSED;
+ if (!closedLeft && !closedRight
+ && this.getLeftEndpoint().equals(this.getRightEndpoint())) {
+ return Boolean.TRUE;
+ }
+ double step = this.getStep().intValue();
+ if (step > 0.0) {
+ double firstValue = closedLeft ? leftValue : leftValue + step;
+ return closedRight ? firstValue > rightValue
+ : firstValue >= rightValue;
+ } else {
+ double firstValue = closedLeft ? leftValue : leftValue + step;
+ return closedRight ? firstValue < rightValue
+ : firstValue <= rightValue;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean contains(Character obj) {
+ if (obj == null) {
+ return Boolean.FALSE;
+ }
+ char leftValue = this.getLeftEndpoint().getValue().charValue();
+ char rightValue = this.getRightEndpoint().getValue().charValue();
+ boolean includeLeft = this.getLeftEndpoint().getBoundType() == BoundType.CLOSED;
+ boolean includeRight = this.getRightEndpoint().getBoundType() == BoundType.CLOSED;
+ int step = this.getStep().intValue();
+ int value = (int) obj.charValue();
+
+ int firstValue = 0;
+ int lastValue = 0;
+
+ if (step < 0.0) {
+ firstValue = includeLeft ? leftValue : leftValue + step;
+ lastValue = includeRight ? rightValue : rightValue + 1;
+ if (value > firstValue || value < lastValue) {
+ return Boolean.FALSE;
+ }
+ } else {
+ firstValue = includeLeft ? leftValue : leftValue + step;
+ lastValue = includeRight ? rightValue : rightValue - 1;
+ if (value < firstValue || value > lastValue) {
+ return Boolean.FALSE;
+ }
+ }
+ return ((double) (value - firstValue) / step + 1) % 1.0 == 0.0;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean containsAll(Collection<Character> col) {
+ if (col == null || col.size() == 0) {
+ return Boolean.FALSE;
+ }
+ boolean r = Boolean.TRUE;
+ for (Character t : col) {
+ if (!this.contains(t)) {
+ r = Boolean.FALSE;
+ break;
+ }
+ }
+ return r;
+ }
+
+}
Added: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/DoubleRange.java
URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/DoubleRange.java?rev=1522355&view=auto
==============================================================================
--- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/DoubleRange.java (added)
+++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/DoubleRange.java Thu Sep 12 04:29:46 2013
@@ -0,0 +1,285 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.functor.range;
+
+import java.util.Iterator;
+
+import org.apache.commons.functor.BinaryFunction;
+import org.apache.commons.lang3.Validate;
+
+/**
+ * A generator for a range of doubles.
+ *
+ * @since 1.0
+ * @version $Revision$ $Date$
+ */
+public class DoubleRange extends NumericRange<Double> {
+
+ // attributes
+ // ---------------------------------------------------------------
+ /**
+ * Left limit.
+ */
+ private final Endpoint<Double> leftEndpoint;
+
+ /**
+ * Right limit.
+ */
+ private final Endpoint<Double> rightEndpoint;
+
+ /**
+ * Increment step.
+ */
+ private final double step;
+
+ /**
+ * Current value.
+ */
+ private double currentValue;
+
+ /**
+ * Calculate default step.
+ */
+ public static final BinaryFunction<Double, Double, Double> DEFAULT_STEP =
+ new BinaryFunction<Double, Double, Double>() {
+
+ public Double evaluate(Double left, Double right) {
+ return left > right ? -1.0d : 1.0d;
+ }
+ };
+
+ // constructors
+ // ---------------------------------------------------------------
+ /**
+ * Create a new DoubleRange.
+ *
+ * @param from start
+ * @param to end
+ */
+ public DoubleRange(Number from, Number to) {
+ this(from.doubleValue(), to.doubleValue());
+ }
+
+ /**
+ * Create a new DoubleRange.
+ *
+ * @param from start
+ * @param to end
+ * @param step increment
+ */
+ public DoubleRange(Number from, Number to, Number step) {
+ this(from.doubleValue(), to.doubleValue(), step.doubleValue());
+ }
+
+ /**
+ * Create a new DoubleRange.
+ *
+ * @param from start
+ * @param to end
+ */
+ public DoubleRange(double from, double to) {
+ this(from, to, DEFAULT_STEP.evaluate(from, to).intValue());
+ }
+
+ /**
+ * Create a new DoubleRange.
+ *
+ * @param from start
+ * @param to end
+ * @param step increment
+ */
+ public DoubleRange(double from, double to, double step) {
+ this(from, DEFAULT_LEFT_BOUND_TYPE, to, DEFAULT_RIGHT_BOUND_TYPE, step);
+ }
+
+ /**
+ * Create a new DoubleRange.
+ *
+ * @param from start
+ * @param to end
+ */
+ public DoubleRange(Endpoint<Double> from, Endpoint<Double> to) {
+ this(from.getValue(), from.getBoundType(), to.getValue(), to.getBoundType(),
+ DEFAULT_STEP.evaluate(from.getValue(), to.getValue()));
+ }
+
+ /**
+ * Create a new DoubleRange.
+ *
+ * @param from start
+ * @param leftBoundType type of left bound
+ * @param to end
+ * @param rightBoundType type of right bound
+ */
+ public DoubleRange(double from, BoundType leftBoundType, double to,
+ BoundType rightBoundType) {
+ this(from, leftBoundType, to, rightBoundType, DEFAULT_STEP.evaluate(from, to));
+ }
+
+ /**
+ * Create a new DoubleRange.
+ *
+ * @param from start
+ * @param to end
+ * @param step increment
+ */
+ public DoubleRange(Endpoint<Double> from, Endpoint<Double> to, double step) {
+ this(from.getValue(), from.getBoundType(), to.getValue(), to.getBoundType(), step);
+ }
+
+ /**
+ * Create a new DoubleRange.
+ *
+ * @param from start
+ * @param leftBoundType type of left bound
+ * @param to end
+ * @param rightBoundType type of right bound
+ * @param step increment
+ */
+ public DoubleRange(double from, BoundType leftBoundType, double to,
+ BoundType rightBoundType, double step) {
+ this.leftEndpoint = Validate
+ .notNull(new Endpoint<Double>(from, leftBoundType),
+ "Left Endpoint argument must not be null");
+ this.rightEndpoint = Validate
+ .notNull(new Endpoint<Double>(to, rightBoundType),
+ "Right Endpoint argument must not be null");
+ this.step = step;
+ if (from != to && Math.signum(step) != Math.signum(to - from)) {
+ throw new IllegalArgumentException("Will never reach " + to
+ + " from " + from
+ + " using step " + step);
+ }
+ if (this.leftEndpoint.getBoundType() == BoundType.CLOSED) {
+ this.currentValue = this.leftEndpoint.getValue();
+ } else {
+ this.currentValue = this.leftEndpoint.getValue() + this.step;
+ }
+ }
+
+ // range methods
+ // ---------------------------------------------------------------
+ /**
+ * {@inheritDoc}
+ */
+ public Endpoint<Double> getLeftEndpoint() {
+ return this.leftEndpoint;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Endpoint<Double> getRightEndpoint() {
+ return this.rightEndpoint;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Double getStep() {
+ return this.step;
+ }
+ // iterable, iterator methods
+ // ---------------------------------------------------------------
+ /**
+ * {@inheritDoc}
+ */
+ public boolean hasNext() {
+ final double to = this.rightEndpoint.getValue();
+ if (step < 0) {
+ if (this.rightEndpoint.getBoundType() == BoundType.CLOSED) {
+ return this.currentValue >= to;
+ } else {
+ return this.currentValue > to;
+ }
+ } else {
+ if (this.rightEndpoint.getBoundType() == BoundType.CLOSED) {
+ return this.currentValue <= to;
+ } else {
+ return this.currentValue < to;
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Double next() {
+ final double step = this.getStep();
+ final double r = this.currentValue;
+ this.currentValue += step;
+ return r;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Iterator<Double> iterator() {
+ return this;
+ }
+
+ // object methods
+ // ---------------------------------------------------------------
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return "DoubleRange<" + this.leftEndpoint.toLeftString() + ", "
+ + this.rightEndpoint.toRightString() + ", " + this.step + ">";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof DoubleRange)) {
+ return false;
+ }
+ DoubleRange that = (DoubleRange) obj;
+ return this.leftEndpoint.equals(that.leftEndpoint)
+ && this.rightEndpoint.equals(that.rightEndpoint)
+ && this.step == that.step;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ int hash = "DoubleRange".hashCode();
+ hash <<= 2;
+ hash ^= this.leftEndpoint.getValue().hashCode();
+ hash <<= 2;
+ hash ^= this.rightEndpoint.getValue().hashCode();
+ hash <<= 2;
+ hash ^= Double.valueOf(this.step).hashCode();
+ return hash;
+ }
+
+}
Added: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/Endpoint.java
URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/Endpoint.java?rev=1522355&view=auto
==============================================================================
--- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/Endpoint.java (added)
+++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/Endpoint.java Thu Sep 12 04:29:46 2013
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.functor.range;
+
+/**
+ * Represent an endpoint of a range. This can be the left endpoint or the right
+ * endpoint. It is also called left limit or right limit, and can be open
+ * (exclusive, unbounded) or closed (inclusive, bounded).
+ *
+ * @param <T> type of the value held by this endpoint
+ * @since 1.0
+ * @version $Revision$ $Date$
+ */
+public class Endpoint<T extends Comparable<?>> {
+
+ /**
+ * The endpoint value.
+ */
+ private final T value;
+
+ /**
+ * The endpoint bound type.
+ */
+ private final BoundType boundType;
+
+ /**
+ * Create an endpoint.
+ *
+ * @param value value
+ * @param boundType bound type
+ */
+ public Endpoint(T value, BoundType boundType) {
+ this.value = value;
+ this.boundType = boundType;
+ }
+
+ /**
+ * @return Object
+ */
+ public T getValue() {
+ return value;
+ }
+
+ /**
+ * @return BoundType
+ */
+ public BoundType getBoundType() {
+ return boundType;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ String boundType = this.boundType == BoundType.OPEN ? "OPEN" : "CLOSED";
+ return "Endpoint<" + this.value + ", " + boundType + ">";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof Endpoint)) {
+ return false;
+ }
+ Endpoint<?> that = (Endpoint<?>) obj;
+ return this.boundType == that.boundType
+ && this.value.equals(that.value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ int hash = "Endpoint".hashCode();
+ hash <<= 2;
+ hash ^= this.value.toString().hashCode();
+ hash <<= 2;
+ hash ^= Boolean.valueOf(this.boundType == BoundType.OPEN).hashCode();
+ return hash;
+ }
+
+ /**
+ * Print the left endpoint and bound type.
+ *
+ * @return String
+ */
+ public String toLeftString() {
+ return (this.boundType == BoundType.OPEN ? "(" : "[") + this.value;
+ }
+
+ /**
+ * Print the right endpoint and bound type.
+ *
+ * @return String
+ */
+ public String toRightString() {
+ return this.value + (this.boundType == BoundType.OPEN ? ")" : "]");
+ }
+
+}
Added: commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/FloatRange.java
URL: http://svn.apache.org/viewvc/commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/FloatRange.java?rev=1522355&view=auto
==============================================================================
--- commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/FloatRange.java (added)
+++ commons/proper/functor/trunk/core/src/main/java/org/apache/commons/functor/range/FloatRange.java Thu Sep 12 04:29:46 2013
@@ -0,0 +1,285 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.functor.range;
+
+import java.util.Iterator;
+
+import org.apache.commons.functor.BinaryFunction;
+import org.apache.commons.lang3.Validate;
+
+/**
+ * A generator for a range of float.
+ *
+ * @since 1.0
+ * @version $Revision$ $Date$
+ */
+public class FloatRange extends NumericRange<Float> {
+
+ // attributes
+ // ---------------------------------------------------------------
+ /**
+ * Left limit.
+ */
+ private final Endpoint<Float> leftEndpoint;
+
+ /**
+ * Right limit.
+ */
+ private final Endpoint<Float> rightEndpoint;
+
+ /**
+ * Increment step.
+ */
+ private final float step;
+
+ /**
+ * Current value.
+ */
+ private float currentValue;
+
+ /**
+ * Calculate default step.
+ */
+ public static final BinaryFunction<Float, Float, Float> DEFAULT_STEP = new BinaryFunction<Float, Float, Float>() {
+
+ public Float evaluate(Float left, Float right) {
+ return left > right ? -1.0f : 1.0f;
+ }
+ };
+
+ // constructors
+ // ---------------------------------------------------------------
+ /**
+ * Create a new FloatRange.
+ *
+ * @param from start
+ * @param to end
+ */
+ public FloatRange(Number from, Number to) {
+ this(from.floatValue(), to.floatValue());
+ }
+
+ /**
+ * Create a new FloatRange.
+ *
+ * @param from start
+ * @param to end
+ * @param step increment
+ */
+ public FloatRange(Number from, Number to, Number step) {
+ this(from.floatValue(), to.floatValue(), step.floatValue());
+ }
+
+ /**
+ * Create a new FloatRange.
+ *
+ * @param from start
+ * @param to end
+ */
+ public FloatRange(float from, float to) {
+ this(from, to, DEFAULT_STEP.evaluate(from, to).floatValue());
+ }
+
+ /**
+ * Create a new FloatRange.
+ *
+ * @param from start
+ * @param to end
+ * @param step increment
+ */
+ public FloatRange(float from, float to, float step) {
+ this(from, DEFAULT_LEFT_BOUND_TYPE, to, DEFAULT_RIGHT_BOUND_TYPE, step);
+ }
+
+ /**
+ * Create a new FloatRange.
+ *
+ * @param from start
+ * @param to end
+ */
+ public FloatRange(Endpoint<Float> from, Endpoint<Float> to) {
+ this(from.getValue(), from.getBoundType(), to.getValue(), to.getBoundType(),
+ DEFAULT_STEP.evaluate(from.getValue(), to.getValue()));
+ }
+
+ /**
+ * Create a new FloatRange.
+ *
+ * @param from start
+ * @param to end
+ * @param step increment
+ */
+ public FloatRange(Endpoint<Float> from, Endpoint<Float> to, float step) {
+ this(from.getValue(), from.getBoundType(), to.getValue(), to.getBoundType(), step);
+ }
+
+ /**
+ * Create a new FloatRange.
+ *
+ * @param from start
+ * @param leftBoundType type of left bound
+ * @param to end
+ * @param rightBoundType type of right bound
+ */
+ public FloatRange(float from, BoundType leftBoundType, float to,
+ BoundType rightBoundType) {
+ this(from, leftBoundType, to, rightBoundType, DEFAULT_STEP.evaluate(from, to));
+ }
+
+ /**
+ * Create a new FloatRange.
+ *
+ * @param from start
+ * @param leftBoundType type of left bound
+ * @param to end
+ * @param rightBoundType type of right bound
+ * @param step increment
+ */
+ public FloatRange(float from, BoundType leftBoundType, float to,
+ BoundType rightBoundType, float step) {
+ this.leftEndpoint = Validate
+ .notNull(new Endpoint<Float>(from, leftBoundType),
+ "Left Endpoint argument must not be null");
+ this.rightEndpoint = Validate
+ .notNull(new Endpoint<Float>(to, rightBoundType),
+ "Right Endpoint argument must not be null");
+ this.step = step;
+ if (from != to && Math.signum(step) != Math.signum(to - from)) {
+ throw new IllegalArgumentException("Will never reach " + to
+ + " from " + from
+ + " using step " + step);
+ }
+ if (this.leftEndpoint.getBoundType() == BoundType.CLOSED) {
+ this.currentValue = this.leftEndpoint.getValue();
+ } else {
+ this.currentValue = this.leftEndpoint.getValue() + this.step;
+ }
+ }
+
+ // range methods
+ // ---------------------------------------------------------------
+ /**
+ * {@inheritDoc}
+ */
+ public Endpoint<Float> getLeftEndpoint() {
+ return this.leftEndpoint;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Endpoint<Float> getRightEndpoint() {
+ return this.rightEndpoint;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Float getStep() {
+ return this.step;
+ }
+
+ // iterable, iterator methods
+ // ---------------------------------------------------------------
+ /**
+ * {@inheritDoc}
+ */
+ public boolean hasNext() {
+ final float to = this.rightEndpoint.getValue();
+ if (step < 0) {
+ if (this.rightEndpoint.getBoundType() == BoundType.CLOSED) {
+ return this.currentValue >= to;
+ } else {
+ return this.currentValue > to;
+ }
+ } else {
+ if (this.rightEndpoint.getBoundType() == BoundType.CLOSED) {
+ return this.currentValue <= to;
+ } else {
+ return this.currentValue < to;
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Float next() {
+ final float step = this.getStep();
+ final float r = this.currentValue;
+ this.currentValue += step;
+ return r;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Iterator<Float> iterator() {
+ return this;
+ }
+
+ // object methods
+ // ---------------------------------------------------------------
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return "FloatRange<" + this.leftEndpoint.toLeftString() + ", "
+ + this.rightEndpoint.toRightString() + ", " + this.step + ">";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof FloatRange)) {
+ return false;
+ }
+ FloatRange that = (FloatRange) obj;
+ return this.leftEndpoint.equals(that.leftEndpoint)
+ && this.rightEndpoint.equals(that.rightEndpoint)
+ && this.step == that.step;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ int hash = "FloatRange".hashCode();
+ hash <<= 2;
+ hash ^= this.leftEndpoint.getValue().hashCode();
+ hash <<= 2;
+ hash ^= this.rightEndpoint.getValue().hashCode();
+ hash <<= 2;
+ hash ^= Float.valueOf(this.step).hashCode();
+ return hash;
+ }
+
+}