Array.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 java.util.*;
import Hoot.Magnitudes.Integer;
import Smalltalk.Magnitudes.Ordinal;
import Smalltalk.Collections.*;
import Smalltalk.Core.Subject;
import Smalltalk.Blocks.*;

public class Array<ElementType extends Object> extends ArrayedCollection<ElementType>
{

  public static Metaclass type() { return (Metaclass)Metaclass.$class; }
  @Override public Metaclass $class() { return (Metaclass)Metaclass.$class; }
  public static class Metaclass extends ArrayedCollection.Metaclass
  {
    static final Array.Metaclass $class = new Array.Metaclass();
    public Metaclass() {
      this(Array.Metaclass.class);
    }

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

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


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

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

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

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

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

    /**
     * @return 
     */
    public  <ElementType extends Subject> Array withThese(final CollectedReadably<ElementType> aCollection)
    {
      java.lang.String exitID = "ArrayMetatype>>withThese";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Array)f0.exit(exitID, new Array(aCollection.asList()));
      });
    }

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

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

    /**
     * @return 
     */
    public   Array<String> withStrings(final java.lang.String ... textStrings)
    {
      java.lang.String exitID = "ArrayMetatype>>withStrings";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Array<String>)f0.exit(exitID, new Array(String.listWith(textStrings)));
      });
    }
  }


  protected ArrayList<ElementType> contents = new ArrayList();

  /**
   * 
   */
  public    Array(final List<ElementType> elements)
  {
    java.lang.String exitID = "Array>>Array";
    Frame f0 = new Frame(exitID);
    contents.addAll(elements);
  }

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

  /**
   * 
   */
  protected    Array(final ElementType ... elements)
  {
    java.lang.String exitID = "Array>>Array";
    Frame f0 = new Frame(exitID);
    contents.addAll(Arrays.asList(elements));
  }

  /**
   * 
   */
  protected    Array(final Integer capacity)
  {
    java.lang.String exitID = "Array>>Array";
    Frame f0 = new Frame(exitID);
    ElementType none = null;

     contents = Utils.fillList(capacity.primitiveInteger(), none);
  }

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

  /**
   * @return 
   */
  public static  <ElementType extends Subject> Array withThese(final CollectedReadably<ElementType> aCollection)
  {
    java.lang.String exitID = "Array>>$withThese";
    Frame f0 = new Frame(exitID);
    return (Array)new Array(aCollection.asList());
  }

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

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

  /**
   * @return 
   */
  @Override protected   ElementType get(final int index)
  {
    java.lang.String exitID = "Array>>get";
    Frame f0 = new Frame(exitID);
    return (ElementType)contents.get(index);
  }

  /**
   * @return 
   */
  @Override protected   ElementType add_at(final ElementType element, final int index)
  {
    java.lang.String exitID = "Array>>add_at";
    Frame f0 = new Frame(exitID);
    contents.add(index, element);
    return (ElementType)element;
  }

  /**
   * @return 
   */
  public   ElementType at_ifAbsent(final Integer index, final NiladicValuable aBlock)
  {
    java.lang.String exitID = "Array>>at_ifAbsent";
    Frame f0 = new Frame(exitID);
    return (ElementType)this.get(this.checkIndex_ifAbsent(index, aBlock));
  }

  /**
   * @return 
   */
  @Override public   ElementType at_put(final Ordinal index, final ElementType element)
  {
    java.lang.String exitID = "Array>>at_put";
    Frame f0 = new Frame(exitID);
    contents.set(this.checkIndex(index), element);
    return (ElementType)element;
  }

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

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

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

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

  /**
   * @return 
   */
  @Override public   Array $do(final MonadicValuable aBlock)
  {
    java.lang.String exitID = "Array>>$do";
    Frame f0 = new Frame(exitID);
    SmallInteger.from(1).to_do(this.size(), Closure.with(f2 -> {
      Integer index = f2.getValue(0).value();
      return aBlock.value(this.get((index.minus(SmallInteger.from(1))).primitiveInteger()));
    }, "index"));
    return (Array)this;
  }

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

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

  /**
   * @return 
   */
  public   ElementType removeLast()
  {
    java.lang.String exitID = "Array>>removeLast";
    Frame f0 = new Frame(exitID);
    this.immutabilityError();
    return (ElementType)((ElementType)Nil.literal());
  }

  /**
   * @return 
   */
  public   ElementType removeFirst()
  {
    java.lang.String exitID = "Array>>removeFirst";
    Frame f0 = new Frame(exitID);
    this.immutabilityError();
    return (ElementType)((ElementType)Nil.literal());
  }

  /**
   * @return 
   */
  public   ElementType removeAtIndex(final Ordinal index)
  {
    java.lang.String exitID = "Array>>removeAtIndex";
    Frame f0 = new Frame(exitID);
    this.immutabilityError();
    return (ElementType)((ElementType)Nil.literal());
  }

  /**
   * @return 
   */
  public   ElementType add(final ElementType element)
  {
    java.lang.String exitID = "Array>>add";
    Frame f0 = new Frame(exitID);
    this.immutabilityError();
    return (ElementType)((ElementType)Nil.literal());
  }
}