appending a sorted list of values to the dynamic array
with this subroutine, a given list of sorted values can be added to the dynamic array. the actual positions of these values 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_longarray_type) | :: | me | ||||
integer(kind=long_k), | intent(in) | :: | val(:) | |||
integer, | intent(in), | optional | :: | length |
optional length to expand the array |
|
integer, | intent(out), | optional | :: | pos(:) |
position in the array, the values are found at. |
|
logical, | intent(out), | optional | :: | wasadded(:) |
flag to indicate, if val was newly added |
subroutine append_da_veclong(me, val, length, pos, wasadded ) !------------------------------------------------------------------------ type(dyn_longarray_type) :: me !< array to append the value to integer(kind=long_k), intent(in) :: val(:) !< values to append !> optional length to expand the array integer, intent(in), optional :: length !> position in the array, the values are found at. integer, intent(out), optional :: pos(:) !> flag to indicate, if val was newly added logical, intent(out), optional :: wasadded(:) !------------------------------------------------------------------------ integer(kind=long_k) :: lastval logical :: addedval(size(val)) integer :: i integer :: veclen integer :: maxlen integer :: nappend integer :: rem_app integer :: curval, ival, iold, iadd integer, allocatable :: newsorted(:) !------------------------------------------------------------------------ if (size(val) == 0) return veclen = size(val) maxlen = veclen + me%nvals allocate(newsorted(maxlen)) addedval = .false. iold = 1 iadd = 1 nappend = 0 curval = 0 ! select the first entry before the loop unconditionally without checks ! for uniqueness (nothing to check against yet). if ( me%val(me%sorted(iold)) <= val(iadd) ) then curval = curval + 1 newsorted(curval) = me%sorted(iold) lastval = me%val(me%sorted(iold)) iold = iold + 1 else curval = curval + 1 nappend = nappend + 1 newsorted(curval) = me%nvals + nappend lastval = val(iadd) if (present(pos)) pos(iadd) = newsorted(curval) addedval(iadd) = .true. iadd = iadd + 1 end if do ival=2,maxlen if ( (iadd <= veclen) .and. (iold <= me%nvals) ) then if ( me%val(me%sorted(iold)) <= val(iadd) ) then ! the original list's values are appended to newsorted before ! the additional list is appended. curval = curval + 1 newsorted(curval) = me%sorted(iold) lastval = me%val(me%sorted(iold)) iold = iold + 1 else ! only append the value to unique lists, if it is not yet in the list. ! (if it is already in the list, it has to be the previous (curval-1) ! entry.) if ( lastval < val(iadd) ) then nappend = nappend + 1 curval = curval + 1 newsorted(curval) = me%nvals + nappend lastval = val(iadd) addedval(iadd) = .true. end if if (present(pos)) pos(iadd) = newsorted(curval) iadd = iadd + 1 end if else ! reached the end of one or both of the sorted lists. exit end if end do if (iold <= me%nvals) then ! still some values from the original list left. newsorted(curval+1:me%nvals+nappend) = me%sorted(iold:me%nvals) end if if (iadd <= veclen) then ! still some values from the list to append left. rem_app = iadd do i = rem_app,veclen if ( lastval < val(iadd) ) then nappend = nappend + 1 curval = curval + 1 newsorted(curval) = me%nvals + nappend lastval = val(iadd) addedval(iadd) = .true. end if if (present(pos)) pos(iadd) = newsorted(curval) iadd = iadd + 1 end do end if if (me%nvals > huge(me%nvals)-nappend) then write(*,*) "reached end of integer range for dynamic array!" write(*,*) "aborting!!" stop end if if (me%nvals + nappend > me%containersize) then call expand( me = me, & & increment = nappend, & & length = length ) end if me%sorted(:me%nvals+nappend) = newsorted(:me%nvals+nappend) curval = me%nvals do iadd=1,veclen if (addedval(iadd)) then curval = curval + 1 me%val(curval) = val(iadd) end if end do me%nvals = me%nvals + nappend if( present( wasadded ) ) wasadded = addedval end subroutine append_da_veclong