Swap#869
Conversation
|
I think this is a great useful addition @jalvesz. program tswap
character(5) :: a = '12345'
character(8) :: b = 'abcdefgh'
print *, a, ' <-> ', b
call swap_str(a,b)
print *, a, ' <-> ', b
contains
elemental subroutine swap_str(lhs,rhs)
character(*), intent(inout) :: lhs, rhs
character(len=max(len(lhs),len(rhs))) :: temp
temp = lhs ; lhs = rhs ; rhs = temp
end subroutine
endthat prints: An option to overcome this issue, would be to fix the string length: character(*), intent(inout) :: lhs
character(len=len(lhs)), intent(inout) :: resand then provide an interface for the |
awvwgk
left a comment
There was a problem hiding this comment.
Thanks for sharing. Can you explicitly test whether swap(x, x) works as expected?
|
@perazz I think that the limitation here is that this swap interface is intended as a "swap values" under the hypothesis of equal kind and type program tswap
character(:), allocatable :: a
character(:), allocatable :: b
a = '12345'
b = 'abcdefgh'
print *, 'Swap values'
print *, a, ' <-> ', b
call swap_str(a,b)
print *, a, ' <-> ', b
a = '12345'
b = 'abcdefgh'
print *, 'Swap mem address'
print *, a, ' <-> ', b
call swap_str_a(a,b)
print *, a, ' <-> ', b
contains
elemental subroutine swap_str(lhs,rhs)
character(*), intent(inout) :: lhs, rhs
character(len=max(len(lhs),len(rhs))) :: temp
temp = lhs ; lhs = rhs ; rhs = temp
end subroutine
subroutine swap_str_a(lhs,rhs)
character(:), allocatable, intent(inout) :: lhs, rhs
character(:), allocatable :: temp
call move_alloc( lhs , temp )
call move_alloc( rhs , lhs )
call move_alloc( temp , rhs )
end subroutine
endNow, these two procedures cannot be interfaced under the same interface as it leads to an ambiguous interface. But a secondary interface can be added to handle this use-case, like We could propose also a swap interface to the |
|
@awvwgk adding something like this ? : subroutine test_swap_${k1}$(error)
type(error_type), allocatable, intent(out) :: error
${t1}$ :: x(3), y(3)
x = [${t1}$ :: 1, 2, 3]
y = [${t1}$ :: 4, 5, 6]
call swap(x,y)
call check(error, all( x == [${t1}$ :: 4, 5, 6] ) )
if (allocated(error)) return
call check(error, all( y == [${t1}$ :: 1, 2, 3] ) )
if (allocated(error)) return
! check self swap
call swap(x,x)
call check(error, all( x == [${t1}$ :: 4, 5, 6] ) )
if (allocated(error)) return
end subroutine test_swap_${k1}$ |
Exactly @jalvesz, so the stdlib user has one more reason to use the provided string type. |
Co-authored-by: Jeremie Vandenplas <jeremie.vandenplas@gmail.com>
Co-authored-by: Jeremie Vandenplas <jeremie.vandenplas@gmail.com>
Co-authored-by: Jeremie Vandenplas <jeremie.vandenplas@gmail.com>
Co-authored-by: Jeremie Vandenplas <jeremie.vandenplas@gmail.com>
Co-authored-by: Jeremie Vandenplas <jeremie.vandenplas@gmail.com>
Co-authored-by: Sebastian Ehlert <28669218+awvwgk@users.noreply.github.com>
|
I've added a warning and extended the example specific to |
|
I think this PR is ready to be merged if there are no further comments? |
|
With 3 approvals and no further comments, I will merge this. |
Proposal to add an elemental swap interface for base kinds
Reference
https://fortranwiki.org/fortran/show/swap by @urbanjost
cc: @jvdp1 @perazz