// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// @dart = 2.6

part of dart.core;

/**
 * A collection of objects in which each object can occur only once.
 *
 * That is, for each object of the element type, the object is either considered
 * to be in the set, or to _not_ be in the set.
 *
 * Set implementations may consider some elements indistinguishable. These
 * elements are treated as being the same for any operation on the set.
 *
 * The default [Set] implementation, [LinkedHashSet], considers objects
 * indistinguishable if they are equal with regard to
 * operator [Object.==].
 *
 * Iterating over elements of a set may be either unordered
 * or ordered in some way. Examples:
 *
 * * A [HashSet] is unordered, which means that its iteration order is
 *   unspecified,
 * * [LinkedHashSet] iterates in the insertion order of its elements, and
 * * a sorted set like [SplayTreeSet] iterates the elements in sorted order.
 *
 * It is generally not allowed to modify the set (add or remove elements) while
 * an operation on the set is being performed, for example during a call to
 * [forEach] or [containsAll]. Nor is it allowed to modify the set while
 * iterating either the set itself or any [Iterable] that is backed by the set,
 * such as the ones returned by methods like [where] and [map].
 *
 * It is generally not allowed to modify the equality of elements (and thus not
 * their hashcode) while they are in the set. Some specialized subtypes may be
 * more permissive, in which case they should document this behavior.
 */
abstract class Set<E> extends EfficientLengthIterable<E> {
  /**
   * Creates an empty [Set].
   *
   * The created [Set] is a plain [LinkedHashSet].
   * As such, it considers elements that are equal (using [operator ==]) to be
   * indistinguishable, and requires them to have a compatible
   * [Object.hashCode] implementation.
   *
   * The set is equivalent to one created by `new LinkedHashSet<E>()`.
   */
  factory Set() = LinkedHashSet<E>;

  /**
   * Creates an empty identity [Set].
   *
   * The created [Set] is a [LinkedHashSet] that uses identity as equality
   * relation.
   *
   * The set is equivalent to one created by `new LinkedHashSet<E>.identity()`.
   */
  factory Set.identity() = LinkedHashSet<E>.identity;

  /**
   * Creates a [Set] that contains all [elements].
   *
   * All the [elements] should be instances of [E].
   * The `elements` iterable itself can have any type,
   * so this constructor can be used to down-cast a `Set`, for example as:
   *
   *     Set<SuperType> superSet = ...;
   *     Set<SubType> subSet =
   *         new Set<SubType>.from(superSet.where((e) => e is SubType));
   *
   * The created [Set] is a [LinkedHashSet]. As such, it considers elements that
   * are equal (using [operator ==]) to be indistinguishable, and requires them to
   * have a compatible [Object.hashCode] implementation.
   *
   * The set is equivalent to one created by
   * `new LinkedHashSet<E>.from(elements)`.
   */
  factory Set.from(Iterable elements) = LinkedHashSet<E>.from;

  /**
   * Creates a [Set] from [elements].
   *
   * The created [Set] is a [LinkedHashSet]. As such, it considers elements that
   * are equal (using [operator ==]) to be indistinguishable, and requires them to
   * have a compatible [Object.hashCode] implementation.
   *
   * The set is equivalent to one created by
   * `new LinkedHashSet<E>.of(elements)`.
   */
  factory Set.of(Iterable<E> elements) = LinkedHashSet<E>.of;

  /**
   * Adapts [source] to be a `Set<T>`.
   *
   * If [newSet] is provided, it is used to create the new sets returned
   * by [toSet], [union], and is also used for [intersection] and [difference].
   * If [newSet] is omitted, it defaults to creating a new set using the
   * default [Set] constructor, and [intersection] and [difference]
   * returns an adapted version of calling the same method on the source.
   *
   * Any time the set would produce an element that is not a [T],
   * the element access will throw.
   *
   * Any time a [T] value is attempted added into the adapted set,
   * the store will throw unless the value is also an instance of [S].
   *
   * If all accessed elements of [source] are actually instances of [T],
   * and if all elements added to the returned set are actually instance
   * of [S],
   * then the returned set can be used as a `Set<T>`.
   */
  static Set<T> castFrom<S, T>(Set<S> source, {Set<R> Function<R>() newSet}) =>
      CastSet<S, T>(source, newSet);

  /**
   * Provides a view of this set as a set of [R] instances.
   *
   * If this set contains only instances of [R], all read operations
   * will work correctly. If any operation tries to access an element
   * that is not an instance of [R], the access will throw instead.
   *
   * Elements added to the set (e.g., by using [add] or [addAll])
   * must be instance of [R] to be valid arguments to the adding function,
   * and they must be instances of [E] as well to be accepted by
   * this set as well.
   */
  Set<R> cast<R>();
  /**
   * Provides an iterator that iterates over the elements of this set.
   *
   * The order of iteration is defined by the individual `Set` implementation,
   * but must be consistent between changes to the set.
   */
  Iterator<E> get iterator;

  /**
   * Returns true if [value] is in the set.
   */
  bool contains(Object value);

  /**
   * Adds [value] to the set.
   *
   * Returns `true` if [value] (or an equal value) was not yet in the set.
   * Otherwise returns `false` and the set is not changed.
   *
   * Example:
   *
   *     var set = new Set();
   *     var time1 = new DateTime.fromMillisecondsSinceEpoch(0);
   *     var time2 = new DateTime.fromMillisecondsSinceEpoch(0);
   *     // time1 and time2 are equal, but not identical.
   *     Expect.isTrue(time1 == time2);
   *     Expect.isFalse(identical(time1, time2));
   *     set.add(time1);  // => true.
   *     // A value equal to time2 exists already in the set, and the call to
   *     // add doesn't change the set.
   *     set.add(time2);  // => false.
   *     Expect.isTrue(set.length == 1);
   *     Expect.isTrue(identical(time1, set.first));
   */
  bool add(E value);

  /**
   * Adds all [elements] to this Set.
   *
   * Equivalent to adding each element in [elements] using [add],
   * but some collections may be able to optimize it.
   */
  void addAll(Iterable<E> elements);

  /**
   * Removes [value] from the set. Returns true if [value] was
   * in the set. Returns false otherwise. The method has no effect
   * if [value] value was not in the set.
   */
  bool remove(Object value);

  /**
   * If an object equal to [object] is in the set, return it.
   *
   * Checks whether [object] is in the set, like [contains], and if so,
   * returns the object in the set, otherwise returns `null`.
   *
   * If the equality relation used by the set is not identity,
   * then the returned object may not be *identical* to [object].
   * Some set implementations may not be able to implement this method.
   * If the [contains] method is computed,
   * rather than being based on an actual object instance,
   * then there may not be a specific object instance representing the
   * set element.
   */
  E lookup(Object object);

  /**
   * Removes each element of [elements] from this set.
   */
  void removeAll(Iterable<Object> elements);

  /**
   * Removes all elements of this set that are not elements in [elements].
   *
   * Checks for each element of [elements] whether there is an element in this
   * set that is equal to it (according to `this.contains`), and if so, the
   * equal element in this set is retained, and elements that are not equal
   * to any element in `elements` are removed.
   */
  void retainAll(Iterable<Object> elements);

  /**
   * Removes all elements of this set that satisfy [test].
   */
  void removeWhere(bool test(E element));

  /**
   * Removes all elements of this set that fail to satisfy [test].
   */
  void retainWhere(bool test(E element));

  /**
   * Returns whether this Set contains all the elements of [other].
   */
  bool containsAll(Iterable<Object> other);

  /**
   * Returns a new set which is the intersection between this set and [other].
   *
   * That is, the returned set contains all the elements of this [Set] that
   * are also elements of [other] according to `other.contains`.
   */
  Set<E> intersection(Set<Object> other);

  /**
   * Returns a new set which contains all the elements of this set and [other].
   *
   * That is, the returned set contains all the elements of this [Set] and
   * all the elements of [other].
   */
  Set<E> union(Set<E> other);

  /**
   * Returns a new set with the elements of this that are not in [other].
   *
   * That is, the returned set contains all the elements of this [Set] that
   * are not elements of [other] according to `other.contains`.
   */
  Set<E> difference(Set<Object> other);

  /**
   * Removes all elements in the set.
   */
  void clear();

  /* Creates a [Set] with the same elements and behavior as this `Set`.
   *
   * The returned set behaves the same as this set
   * with regard to adding and removing elements.
   * It initially contains the same elements.
   * If this set specifies an ordering of the elements,
   * the returned set will have the same order.
   */
  Set<E> toSet();
}
