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