Set.java

/**
* Copyright 2010,2021 Nikolas S Boyd.
Permission is granted to copy this work provided this copyright statement is retained in all copies.

*/
package Hoot.Collections;

import Hoot.Runtime.Functions.*;
import Hoot.Runtime.Faces.*;
import Hoot.Runtime.Values.*;
import Hoot.Runtime.Blocks.*;
import Smalltalk.Core.*;
import Smalltalk.Blocks.*;
import Smalltalk.Magnitudes.*;
import Hoot.Behaviors.*;
import Hoot.Behaviors.Nil;
import Hoot.Behaviors.Object;
import Hoot.Behaviors.True;
import Hoot.Behaviors.False;
import Hoot.Behaviors.Boolean;
import Hoot.Magnitudes.*;
import Hoot.Magnitudes.Integer;
import Hoot.Magnitudes.Character;
import Hoot.Magnitudes.Float;
import Hoot.Magnitudes.Double;
import Hoot.Magnitudes.Number;
import Hoot.Magnitudes.Integer;
import Hoot.Runtime.Names.Selector;
import Smalltalk.Core.Subject;
import Smalltalk.Collections.*;
import Smalltalk.Magnitudes.Ordinal;
import Smalltalk.Streams.StreamWriter;
import java.util.Arrays;

public class Set<ElementType extends Object> extends Collection<ElementType> implements CollectedDistinctly<ElementType>
{

  public static Metaclass type() { return (Metaclass)Metaclass.$class; }
  @Override public Metaclass $class() { return (Metaclass)Metaclass.$class; }
  public static class Metaclass extends Collection.Metaclass implements CollectedDistinctly.Metatype
  {
    static final Set.Metaclass $class = new Set.Metaclass();
    public Metaclass() {
      this(Set.Metaclass.class);
    }

    public Metaclass(java.lang.Class aClass) {
      super(aClass);
    }

    @Override public java.lang.Class outerClass() { return Set.class; }


    /**
     * @return 
     */
    @Override public  <ElementType extends Subject> Set with(final ElementType a)
    {
      java.lang.String exitID = "SetMetatype>>with";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Set)f0.exit(exitID, ((Set)this.withAll(((Object)a))));
      });
    }

    /**
     * @return 
     */
    @Override public  <ElementType extends Subject> Set with_with(final ElementType a, final ElementType b)
    {
      java.lang.String exitID = "SetMetatype>>with_with";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Set)f0.exit(exitID, ((Set)this.withAll(((Object)a), ((Object)b))));
      });
    }

    /**
     * @return 
     */
    @Override public  <ElementType extends Subject> Set with_with_with(final ElementType a, final ElementType b, final ElementType c)
    {
      java.lang.String exitID = "SetMetatype>>with_with_with";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Set)f0.exit(exitID, ((Set)this.withAll(((Object)a), ((Object)b), ((Object)c))));
      });
    }

    /**
     * @return 
     */
    @Override public  <ElementType extends Subject> Set with_with_with_with(final ElementType a, final ElementType b, final ElementType c, final ElementType d)
    {
      java.lang.String exitID = "SetMetatype>>with_with_with_with";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Set)f0.exit(exitID, ((Set)this.withAll(((Object)a), ((Object)b), ((Object)c), ((Object)d))));
      });
    }

    /**
     * @return 
     */
    @Override public  <ElementType extends Subject> Set withAll(final CollectedReadably<ElementType> elements)
    {
      java.lang.String exitID = "SetMetatype>>withAll";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Set)f0.exit(exitID, ((Set)super.withAll(elements)));
      });
    }

    /**
     * @return 
     */
    public  <ElementType extends Object> Set<ElementType> withAll(final ElementType ... elements)
    {
      java.lang.String exitID = "SetMetatype>>withAll";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Set<ElementType>)f0.exit(exitID, Set.from(Arrays.asList(elements)));
      });
    }

    /**
     * @return 
     */
    @Override public   Set $new()
    {
      java.lang.String exitID = "SetMetatype>>$new";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Set)f0.exit(exitID, this.$new(SmallInteger.from(10)));
      });
    }

    /**
     * @return 
     */
    @Override public   Set $new(final Ordinal capacity)
    {
      java.lang.String exitID = "SetMetatype>>$new";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Set)f0.exit(exitID, new Set(capacity));
      });
    }

    /**
     * @return 
     */
    public  <ElementType> Set synchronizedFrom(final java.util.Set<ElementType> primitiveSet)
    {
      java.lang.String exitID = "SetMetatype>>synchronizedFrom";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Set)f0.exit(exitID, new Set(java.util.Collections.synchronizedSet(primitiveSet)));
      });
    }
  }


  protected java.util.Set<ElementType> contents = new java.util.HashSet();

  /**
   * 
   */
  protected    Set()
  {
    java.lang.String exitID = "Set>>Set";
    Frame f0 = new Frame(exitID);
  }

  /**
   * 
   */
  protected    Set(final Ordinal capacity)
  {
    java.lang.String exitID = "Set>>Set";
    Frame f0 = new Frame(exitID);
     contents = new java.util.HashSet(capacity.intValue());
  }

  /**
   * 
   */
  protected    Set(final java.util.Set primitiveSet)
  {
    java.lang.String exitID = "Set>>Set";
    Frame f0 = new Frame(exitID);
     contents = primitiveSet;
  }

  /**
   * @return 
   */
  public static  <ElementType extends Object> Set<ElementType> from(final java.util.Set<ElementType> primitiveSet)
  {
    java.lang.String exitID = "Set>>$from";
    Frame f0 = new Frame(exitID);
    return (Set<ElementType>)new Set(primitiveSet);
  }

  /**
   * @return 
   */
  public static  <ElementType extends Object> Set<ElementType> from(final java.util.List<ElementType> aList)
  {
    java.lang.String exitID = "Set>>$from";
    Frame f0 = new Frame(exitID);
    return (Set<ElementType>)Set.from(new java.util.HashSet(aList));
  }

  /**
   * @return 
   */
  public static   Set<Symbol> fromSelectors(final java.util.Set<Selector> selectors)
  {
    java.lang.String exitID = "Set>>$fromSelectors";
    Frame f0 = new Frame(exitID);
    return (Set<Symbol>)new Set(Closure.with(f2 -> {
      Selector s = f2.getValue(0).value();
      return Symbol.from(s.name());
    }, "s").evaluateWithEach(selectors));
  }

  /**
   * @return 
   */
  public   java.util.Set<ElementType> primitiveContents()
  {
    java.lang.String exitID = "Set>>primitiveContents";
    Frame f0 = new Frame(exitID);
    return (java.util.Set<ElementType>)contents;
  }

  /**
   * @return 
   */
  @Override public   Integer size()
  {
    java.lang.String exitID = "Set>>size";
    Frame f0 = new Frame(exitID);
    return (Integer)SmallInteger.from(contents.size());
  }

  /**
   * @return 
   */
  public   ElementType add(final ElementType element)
  {
    java.lang.String exitID = "Set>>add";
    Frame f0 = new Frame(exitID);
    contents.add(element);
    return (ElementType)element;
  }

  /**
   * @return 
   */
  public   Collected<ElementType> addAll(final Collected<ElementType> elements)
  {
    java.lang.String exitID = "Set>>addAll";
    Frame f0 = new Frame(exitID);
    elements.$do(Closure.with(f2 -> {
      ElementType element = f2.getValue(0).value();
      return this.add(element);
    }, "element"));
    return (Collected<ElementType>)elements;
  }

  /**
   * @return 
   */
  @Override public   int hashCode()
  {
    java.lang.String exitID = "Set>>hashCode";
    Frame f0 = new Frame(exitID);
    return (int)contents.hashCode();
  }

  /**
   * @return 
   */
  @Override public   Boolean equals(final Collected<ElementType> aCollection)
  {
    java.lang.String exitID = "Set>>equals";
    Frame f0 = new Frame(exitID);
    return (Boolean)(this.equals(aCollection.asSet()));
  }

  /**
   * @return 
   */
  public   Boolean equals(final CollectedDistinctly<ElementType> aSet)
  {
    java.lang.String exitID = "Set>>equals";
    Frame f0 = new Frame(exitID);
    return (Boolean)Boolean.from(contents.equals(((Set)aSet).primitiveContents()));
  }

  /**
   * @return 
   */
  @Override public   Set<ElementType> asSet()
  {
    java.lang.String exitID = "Set>>asSet";
    Frame f0 = new Frame(exitID);
    return (Set<ElementType>)this;
  }

  /**
   * @return 
   */
  @Override public   Set $do(final MonadicValuable aBlock)
  {
    java.lang.String exitID = "Set>>$do";
    Frame f0 = new Frame(exitID);
    Closure.with(f2 -> {
      ElementType element = f2.getValue(0).value();
      return aBlock.value(element);
    }, "element").evaluateWithEach(contents);
    return (Set)this;
  }

  /**
   * @return 
   */
  public   Set removeAll()
  {
    java.lang.String exitID = "Set>>removeAll";
    Frame f0 = new Frame(exitID);
    contents.clear();
    return (Set)this;
  }

  /**
   * @return 
   */
  public   ElementType remove(final ElementType element)
  {
    java.lang.String exitID = "Set>>remove";
    Frame f0 = new Frame(exitID);
    return (ElementType)this.remove_ifAbsent(element, Closure.with(f2 -> {
      return this.elementNotFound();
    }, ""));
  }

  /**
   * @return 
   */
  public   ElementType remove_ifAbsent(final ElementType element, final NiladicValuable aBlock)
  {
    java.lang.String exitID = "Set>>remove_ifAbsent";
    Frame f0 = new Frame(exitID);
    boolean removed = contents.remove(element);
    Boolean.from(removed).ifFalse(aBlock);
    return (ElementType)element;
  }

  /**
   * @return 
   */
  public   Collected<ElementType> removeAll(final Collected<ElementType> elements)
  {
    java.lang.String exitID = "Set>>removeAll";
    Frame f0 = new Frame(exitID);
    elements.$do(Closure.with(f2 -> {
      ElementType element = f2.getValue(0).value();
      return this.remove(element);
    }, "element"));
    return (Collected<ElementType>)elements;
  }

  /**
   * @return 
   */
  public   Set<ElementType> removeAllSuchThat(final MonadicPredicate criteria)
  {
    java.lang.String exitID = "Set>>removeAllSuchThat";
    Frame f0 = new Frame(exitID);
    Set<ElementType> results = Set.type().$new();
    this.$do(Closure.with(f2 -> {
      ElementType element = f2.getValue(0).value();
      return criteria.value(element).ifTrue(Closure.with(f3 -> {
      results.add(element);
    return this.remove(element);
    }, ""));
    }, "element"));
    return (Set<ElementType>)results;
  }

  /**
   * @return 
   */
  public   StreamWriter<ElementType> writeStream()
  {
    java.lang.String exitID = "Set>>writeStream";
    Frame f0 = new Frame(exitID);
    return (StreamWriter<ElementType>)null;
  }

  /**
   * @return 
   */
  @Override public   Boolean includes(final Subject element)
  {
    java.lang.String exitID = "Set>>includes";
    Frame f0 = new Frame(exitID);
    return (Boolean)Boolean.from(contents.contains(element));
  }
}