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

container/Buffer.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 Buffer
#
#  Author: Fridtjof Siebert (siebert@tokiwa.software)
#
# -----------------------------------------------------------------------

# Buffer -- one-dimensional mutable buffer with effect
#
# Buffer can be used to implement ranges of mutable memory that may be
# visible to the outside or even may be modified by the outside.  Examples
# are memory mapped files, memory shared between processes, bitmaps on a
# display, memory mapped I/O, etc.
#
# To model the effects of reading or writing a buffer, an effect is given
# as an argument to a buffer.  This effect should implement the operations
# required to implement the `index []` and `set []` features as needed by
# the backend.  This could be done via direct memory accesses, as for `mmap`
# memory used in a native backend, or via an API such as `java.nio.ByteBuffer`
# for a JVM backend.
#
module:public Buffer
  (# type of elements stored in this buffer
   T type,

   # effect used to modify this buffer
   E type : mutate) ref

is


  # length of this buffer.
  #
  public length i64 => abstract


  # is this empty?
  #
  public is_empty bool => length = 0


  # a sequence of all valid indices to access this array. Useful e.g., for
  # `for`-loops:
  #
  #     for i in arr.indices do
  #       say arr[i]
  #
  public indices interval i64 => (i64 0)..length-1


  # A buffer might be inaccessible, e.g. because it is a shared mutate.array that
  # is not accessible by the current thread.
  #
  public is_accessible bool
  =>
    true


  # get element at index i
  #
  public index [ ] (I type : integer, i I) T ! E
    pre
      safety: 0 ? i.as_i64 < length
      safety: is_accessible
  =>
    abstract


  # set element at index i to value o
  #
  public set [ ] (I type : integer, i I, o T) unit ! E
    pre
      safety: 0 ? i.as_i64 < length
      safety: is_accessible
  =>
    abstract


  # does this buffer contain elem?
  #
  public contains(elem T) bool
    pre T : property.equatable
  =>
    for i in indices
    until Buffer.this[i] = elem
      true
    else
      false


  # create immutable array from this taking at most max_length elements
  #
  public as_array(I type : integer, max_length I) universe.array T
    pre debug: max_length.as_i64 <= length
  =>
    array max_length (index [])


  # convert this buffer to an immutable array
  #
  public as_array array T ! E
    pre
      safety: is_accessible
  =>
    array length (index [])


  # create a list from this buffer
  #
  public as_list list T
    pre
      safety: is_accessible
  =>
    # since buffer is mutable,
    # we first copy the elements
    # to an immutable array.
    as_array.as_list


  # string representation of this buffer's contents
  #
  public redef as_string String
  =>
    if is_accessible
      $as_array
    else
      "inaccessible '$(Buffer.this.type)'"

last changed: 2026-09-10