001/*
002 * Copyright (c) 2012-2017 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 */
009
010package gololang;
011
012import java.util.Collection;
013
014/**
015 * Represents a generic value range.
016 * <p>
017 * A range represent a set of values between to bounds, optionally with a step (or increment) from
018 * one value to the next.
019 */
020public interface Range<T> extends Collection<T>, HeadTail<T> {
021
022  /**
023   * Gets the lower bound of the range.
024   *
025   * @return the starting value of the range.
026   */
027  T from();
028
029  /**
030   * Gets the upper bound of the range.
031   *
032   * @return the excluded ending value of the range.
033   */
034  T to();
035
036  /**
037   * Gets the increment of the range.
038   *
039   * @return the number of value to between two elements in the range.
040   */
041  int increment();
042
043  /**
044   * Sets the increment of the range.
045   *
046   * @param value the new increment.
047   * @return the range itself.
048   */
049  Range<T> incrementBy(int value);
050
051  /**
052   * Sets the negative increment of the range.
053   *<p>
054   * this is equivalent to:
055   * <pre class="listing"><code class="lang-java" data-lang="java">
056   * range.incrementBy(-value)
057   * </code></pre>
058   *
059   * @param value the new increment.
060   * @return the range itself.
061   */
062  Range<T> decrementBy(int value);
063
064  /**
065   * Checks if the range encloses the value.
066   * <p>
067   * i.e. if {@code from() <= value} and {@code value < to()} (for positive increments, resp. for
068   * negative ones), regardless the increment value.
069   * <p>
070   * For instance a range between 0 and 5 with an increment of 2 encloses 1 but don't contains it.
071   *
072   * @param value the value to check.
073   */
074  boolean encloses(T value);
075
076  /**
077   * Creates a new reversed range from this range.
078   * <p>
079   * i.e. swaps the {@code from()} and {@code to()} values and sets the increment to
080   * {@code -increment()}.
081   */
082  Range<T> reversed();
083}