// 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>`.
  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>();

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