String Functions in Co-array Fortran

Co-array Fortran doesn’t have a direct equivalent to the strings package in Go. However, we can demonstrate similar string operations using intrinsic functions and custom subroutines. Here’s an example showcasing various string operations in Co-array Fortran:

program string_functions
  implicit none
  
  ! We'll use these variables for our examples
  character(len=:), allocatable :: str1, str2
  character(len=10) :: result
  integer :: count, index
  logical :: contains, has_prefix, has_suffix
  
  ! Allocate and initialize our strings
  str1 = "test"
  str2 = "es"
  
  ! Contains
  contains = index(str1, str2) > 0
  print *, "Contains:  ", contains
  
  ! Count
  count = count_occurrences(str1, "t")
  print *, "Count:     ", count
  
  ! HasPrefix
  has_prefix = str1(1:2) == "te"
  print *, "HasPrefix: ", has_prefix
  
  ! HasSuffix
  has_suffix = str1(len(str1)-1:) == "st"
  print *, "HasSuffix: ", has_suffix
  
  ! Index
  index = index(str1, "e")
  print *, "Index:     ", index
  
  ! Join (using a custom function)
  print *, "Join:      ", join(["a", "b"], "-")
  
  ! Repeat
  print *, "Repeat:    ", repeat("a", 5)
  
  ! Replace (using a custom function)
  print *, "Replace:   ", replace("foo", "o", "0")
  print *, "Replace:   ", replace_first("foo", "o", "0")
  
  ! Split (using a custom function)
  call split("a-b-c-d-e", "-")
  
  ! ToLower and ToUpper
  result = "TEST"
  call lowercase(result)
  print *, "ToLower:   ", trim(result)
  
  result = "test"
  call uppercase(result)
  print *, "ToUpper:   ", trim(result)

contains

  function count_occurrences(str, substr) result(occurrences)
    character(len=*), intent(in) :: str, substr
    integer :: occurrences, pos
    occurrences = 0
    pos = index(str, substr)
    do while (pos > 0)
      occurrences = occurrences + 1
      pos = index(str(pos+1:), substr)
    end do
  end function count_occurrences

  function join(arr, delimiter) result(joined)
    character(len=*), intent(in) :: arr(:), delimiter
    character(len=:), allocatable :: joined
    integer :: i
    joined = arr(1)
    do i = 2, size(arr)
      joined = joined // delimiter // arr(i)
    end do
  end function join

  function replace(str, old, new) result(replaced)
    character(len=*), intent(in) :: str, old, new
    character(len=:), allocatable :: replaced
    integer :: pos
    replaced = str
    pos = index(replaced, old)
    do while (pos > 0)
      replaced = replaced(:pos-1) // new // replaced(pos+len(old):)
      pos = index(replaced, old)
    end do
  end function replace

  function replace_first(str, old, new) result(replaced)
    character(len=*), intent(in) :: str, old, new
    character(len=:), allocatable :: replaced
    integer :: pos
    replaced = str
    pos = index(replaced, old)
    if (pos > 0) then
      replaced = replaced(:pos-1) // new // replaced(pos+len(old):)
    end if
  end function replace_first

  subroutine split(str, delimiter)
    character(len=*), intent(in) :: str, delimiter
    character(len=:), allocatable :: temp
    integer :: pos
    temp = str
    pos = index(temp, delimiter)
    do while (pos > 0)
      print *, temp(:pos-1)
      temp = temp(pos+len(delimiter):)
      pos = index(temp, delimiter)
    end do
    print *, temp
  end subroutine split

  subroutine lowercase(str)
    character(len=*), intent(inout) :: str
    integer :: i, j
    character(len=26), parameter :: upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    character(len=26), parameter :: lower = 'abcdefghijklmnopqrstuvwxyz'
    do i = 1, len_trim(str)
      j = index(upper, str(i:i))
      if (j > 0) str(i:i) = lower(j:j)
    end do
  end subroutine lowercase

  subroutine uppercase(str)
    character(len=*), intent(inout) :: str
    integer :: i, j
    character(len=26), parameter :: upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    character(len=26), parameter :: lower = 'abcdefghijklmnopqrstuvwxyz'
    do i = 1, len_trim(str)
      j = index(lower, str(i:i))
      if (j > 0) str(i:i) = upper(j:j)
    end do
  end subroutine uppercase

end program string_functions

This program demonstrates various string operations in Co-array Fortran. Since Fortran doesn’t have a built-in string manipulation package like Go’s strings, we’ve implemented some custom functions and subroutines to achieve similar functionality.

To run the program, save it as string_functions.f90 and compile it using a Fortran compiler that supports Co-array Fortran. Then run the executable:

$ gfortran -fcoarray=single string_functions.f90 -o string_functions
$ ./string_functions

The output will be similar to:

 Contains:   T
 Count:           2
 HasPrefix:  T
 HasSuffix:  T
 Index:           2
 Join:      a-b
 Repeat:    aaaaa
 Replace:   f00
 Replace:   f0o
 a
 b
 c
 d
 e
 ToLower:   test
 ToUpper:   TEST

Note that Co-array Fortran is an extension of Fortran for parallel programming. In this example, we’re not using any co-array specific features, so the code will run as a regular Fortran program.