// 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.

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 `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 `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:
  /// ```dart
  /// Set<SuperType> superSet = ...;
  /// Set<SubType> subSet =
  ///     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
  /// `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
  /// `LinkedHashSet<E>.of(elements)`.
  factory Set.of(Iterable<E> elements) = LinkedHashSet<E>.of;

  /// Creates an unmodifiable [Set] from [elements].
  ///
  /// The new set behaves like the result of [Set.of],
  /// except that the set returned by this constructor is not modifiable.
  @Since("2.12")
  factory Set.unmodifiable(Iterable<E> elements) =>
      UnmodifiableSetView<E>(<E>{...elements});

  /// 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>`.
  ///
  /// Methods which accept one or more `Object?` as argument,
  /// like [contains], [remove] and [removeAll],
  /// will pass the argument directly to the this set's method
  /// without any checks.
  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.
  ///
  /// Methods which accept one or more `Object?` as argument,
  /// like [contains], [remove] and [removeAll],
  /// will pass the argument directly to the this set's method
  /// without any checks.
  /// That means that you can do `setOfStrings.cast<int>().remove("a")`
  /// successfully, even if it looks like it shouldn't have any effect.
  Set<R> cast<R>();

  /// 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;

  /// Whether [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:
  /// ```dart
  /// var set = Set();
  /// var time1 = DateTime.fromMillisecondsSinceEpoch(0);
  /// var time2 = DateTime.fromMillisecondsSinceEpoch(0);
  /// // time1 and time2 are equal, but not identical.
  /// assert(time1 == time2);
  /// assert(!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.
  /// assert(set.length == 1);
  /// assert(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, and `false` if not.
  /// The method has no effect if [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));

  /// Whether this set contains all the elements of [other].
  bool containsAll(Iterable<Object?> other);

  /// Creates 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);

  /// Creates 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);

  /// Creates 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 from 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();
}
