invert_segment_list Subroutine

public pure subroutine invert_segment_list(list)

This subroutine inverts a list of segment ranges representing Unicode characters. It compute the complement of the given ranges and modifies the list accordingly.

Arguments

Type IntentOptional Attributes Name
type(segment_t), intent(inout), allocatable :: list(:)

Source Code

   pure subroutine invert_segment_list(list)
      implicit none
      type(segment_t), intent(inout), allocatable :: list(:)
      type(segment_t), allocatable :: new_list(:)

      integer :: i, n, count
      integer :: current_min

      if (.not. allocated(list)) return

      ! sort and merge segments
      call sort_segment_by_min(list)
      call merge_segments(list)

      ! Count the number of new segments
      count = 0
      current_min = UTF8_CODE_EMPTY+1
      n = size(list, dim=1)

      do i = 1, n
         if (current_min < list(i)%min) then
            count = count + 1
         end if
         current_min = list(i)%max + 1
      end do

      if (current_min <= UTF8_CODE_MAX) then
         count = count + 1
      end if

      ! Allocate new list
      allocate(new_list(count))

      ! Fill the new list with the component segments
      count = 1
      current_min = UTF8_CODE_MIN

      do i = 1, n
         if (current_min < list(i)%min) then
            new_list(count)%min = current_min
            new_list(count)%max = list(i)%min - 1
            count = count + 1
         end if
         current_min = list(i)%max + 1
      end do

      if (current_min <= UTF8_CODE_MAX) then
         new_list(count)%min = current_min
         new_list(count)%max = UTF8_CODE_MAX
      end if

      ! Deallocate old list and reassign new list
      deallocate(list)
      list = new_list
   end subroutine invert_segment_list