appending a value to the dynamic array
with this subroutine, a given value can be added to the dynamic array. the actual position of this value in the dynamic array will be returned, so it can be found again easily later. with the wasadded flag, it is indicated,\n wasadded = true, if this entry had to be added,\n wasadded = false, if this was already found in the array.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(dyn_labelarray_type) | :: | me | ||||
character(len=*), | intent(in) | :: | val | |||
integer, | intent(in), | optional | :: | length |
optional length to expand the array |
|
integer, | intent(out), | optional | :: | pos |
position in the array, if the value is found |
|
logical, | intent(out), | optional | :: | wasadded |
flag to indicate, if val was newly added |
subroutine append_da_label(me, val, length, pos, wasadded ) !------------------------------------------------------------------------ type(dyn_labelarray_type) :: me !< array to append the value to character(len=*), intent(in) :: val !< value to append !> optional length to expand the array integer, intent(in), optional :: length !> position in the array, if the value is found integer, intent(out), optional :: pos !> flag to indicate, if val was newly added logical, intent(out), optional :: wasadded !------------------------------------------------------------------------ integer :: foundpos integer :: i !------------------------------------------------------------------------ ! do a binary search on existing entries (returns closest entry next to ! it if not found). foundpos = sortedposofval(me, val, .true.) if( present( wasadded ) ) wasadded = .false. ! if it found the value, the position is smaller than nvals if (foundpos <= me%nvals) then ! the returned position might actually be the right entry already or ! not, check for this here. if ( me%val(me%sorted(foundpos)) == val ) then ! found the value in a list of unique values, ! nothing to do, just return its position. if( present( pos ) ) pos = me%sorted(foundpos) else ! need to append a new value! if (me%nvals == huge(me%nvals)) then write(*,*) "reached end of integer range for dynamic array!" write(*,*) "aborting!!" stop end if if( present( wasadded ) ) wasadded = .true. if (me%nvals == me%containersize) then ! container is full, need to expand it call expand(me = me, length = length) end if me%nvals = me%nvals + 1 ! put the new value into the last position in the ! array. me%val(me%nvals) = val do while( foundpos < me%nvals ) if(me%val(me%sorted(foundpos)) /= val) then exit end if ! in case of multiple entries with the same value ! move on to the first differing entry. foundpos = foundpos + 1 end do ! shift the sorted list of indices, to create a ! whole for the value to be inserted, at position ! foundpos. do i=me%nvals-1,foundpos,-1 me%sorted(i+1) = me%sorted(i) end do ! put the index of the new value into the ! sorted list at the now freed position. me%sorted(foundpos) = me%nvals if( present( pos ) ) pos = me%nvals end if else ! value to append is larger than all existing ones, ! just put it to the end of the list, this captures ! also the case of empty lists. ! in this case foundpos = me%nvals + 1 holds. if( present( wasadded ) ) wasadded = .true. if (foundpos > me%containersize) then ! expand the array, if its boundary is reached call expand(me = me, length = length) end if me%nvals = foundpos me%val(foundpos) = val me%sorted(foundpos) = foundpos if( present( pos ) ) pos = foundpos end if end subroutine append_da_label