Fuzion Logo
fuzion-lang.dev — The Fuzion Language Portal
JavaScript seems to be disabled. Functionality is limited.

array2.fz


# This file is part of the Fuzion language implementation.
#
# The Fuzion language implementation is free software: you can redistribute it
# and/or modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation, version 3 of the License.
#
# The Fuzion language implementation is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License along with The
# Fuzion language implementation.  If not, see <https://www.gnu.org/licenses/>.


# -----------------------------------------------------------------------
#
#  Tokiwa Software GmbH, Germany
#
#  Source code of Fuzion standard library feature array(l1,l2)
#
#  Author: Fridtjof Siebert (siebert@tokiwa.software)
#
# -----------------------------------------------------------------------


# array(length0, length1) -- two-dimensional immutable array
#
# array provides two-dimensional immutable arrays. These are actually
# one-dimensional immutable arrays with an additional access function with
# two index parameters.
#
private:public array2(
       public T type,
       public length0, length1 i32,
       module redef internal_array fuzion.sys.internal_array T,
       _ unit,
       _ unit)
 : array internal_array unit unit unit
  pre
    safety: length0 ≥ 0
    safety: length1 ≥ 0
    safety: length0 *? length1 >=? 0
is

  internal_array.freeze

  # indices range in first dimension
  #
  public indices0 interval i32 => 0..length0-1


  # indices range in second dimension
  #
  public indices1 interval i32 => 0..length1-1

  # all pairs of indices: (0,0), (0,1), (0,2), .. (length0-1, length1-1)
  #
  public index_pairs Sequence (tuple i32 i32) =>
    indices0.flat_map i->
      indices1.map j->(i,j)


  public index [ ] (i1, i2 i32) T
    pre
      safety: 0 ≤ i1 < length0
      safety: 0 ≤ i2 < length1
  =>
    array2.this[i1 * length1 + i2]


  # create a string representation of this array including all the string
  # representations of its contents, separated by ',' and enclosed in '['
  # and ']'.  Arrays in inner dimensions are grouped using '[' and ']'.
  #
  public redef as_string  String : encodings =>
    c =>
      indices0
        .map (i -> "  " + (slice i*length1 (i+1)*length1))
        .fold (String.concat ","+ascii.lf_str)
    "[{ascii.lf_str}$c{ascii.lf_str}]"



  # get a list of tuples indices and elements in this array
  #
  public enumerate2 list (i32, i32, T) =>
    if length = 0 then nil else enumerate_cons 0 0


  # create a cons cell for a list of tuples of this array's indices and elements
  # starting at the given indices.
  #
  enumerate_cons (i, j i32) : Cons (i32, i32, T) (list (tuple i32 i32 T))
    pre
      debug: 0 ≤ i < length0
      debug: 0 ≤ j < length1
  is
    public redef head tuple i32 i32 T => (i, j, index[] i j)
    public redef tail list (tuple i32 i32 T) =>
      if      j < length1-1 then enumerate_cons i j+1
      else if i < length0-1 then enumerate_cons i+1 0
      else                       nil


  # the transpose of the array
  #
  # flips the array along its diagonal
  #
  public transpose array2 T =>
    (array2 T).new length1 length0 i,j->index[](j, i)


  # create an array2 from a Sequence of a Sequence of elements
  #
  public type.create2(s Sequence (Sequence T)) array2 T =>
    a := s.map s1->s1.as_array
          .as_array
    (array2 T).new a.count a[0].count i,j->a[i][j]



  # array(length0, length1) -- two-dimensional immutable array
  #
  # array provides two-dimensional immutable arrays. These are actually
  # one-dimensional immutable arrays with an additional access function with
  # two index parameters.
  #
  public type.new(length0, length1 i32,
                  init2 (i32, i32) -> T) array2 T
    pre
      safety: length0 ≥ 0
      safety: length1 ≥ 0
      safety: length0 *? length1 >=? 0
  =>

    internal_array := fuzion.sys.internal_array_init T length0*length1
    for i1 in 0..length0-1 do
      for i2 in 0..length1-1 do
        internal_array[i1 * length1 + i2] := init2 i1 i2

    array2 length0 length1 internal_array unit unit



# array(length0, length1) -- two-dimensional immutable array
#
# array provides two-dimensional immutable arrays. These are actually
# one-dimensional immutable arrays with an additional access function with
# two index parameters.
#
public array2(T type,
              length0, length1 i32,
              init2 (i32, i32) -> T) array2 T
  pre
    safety: length0 ≥ 0
    safety: length1 ≥ 0
    safety: length0 *? length1 >=? 0
=>
  (array2 T).new length0 length1 init2
last changed: 2025-06-17