From fe02d4b3af099f155296e0a1eee136ed2f229388 Mon Sep 17 00:00:00 2001 From: jalvesz Date: Tue, 3 Sep 2024 22:04:46 +0200 Subject: [PATCH 01/15] elemental swap --- doc/specs/stdlib_math.md | 32 ++++++++++++++++++++++ example/math/CMakeLists.txt | 1 + example/math/example_math_swap.f90 | 33 +++++++++++++++++++++++ src/stdlib_math.fypp | 43 +++++++++++++++++++++++++++++- 4 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 example/math/example_math_swap.f90 diff --git a/doc/specs/stdlib_math.md b/doc/specs/stdlib_math.md index f8cf15227..71806a9dc 100644 --- a/doc/specs/stdlib_math.md +++ b/doc/specs/stdlib_math.md @@ -61,6 +61,38 @@ Here inputs are of type `real` and kind `sp` {!example/math/example_clip_real.f90!} ``` + +### `swap` function + +#### Description + +Swaps the values in `lhs` and `rhs`. + +#### Syntax + +`call` [[stdlib_math(module):swap(interface)]] ` (lhs, rhs)` + +#### Status + +Experimental + +#### Class + +Elemental function. + +#### Argument(s) + +`lhs`: scalar or array of any of the intrinsic types `integer`, `real`, `complex`, `logical`, `character` type. This argument is `intent(inout)`. +`rhs`: scalar or array of any of the intrinsic types `integer`, `real`, `complex`, `logical`, `character` type. This argument is `intent(inout)`. + +Note: All arguments must have same `type` and same `kind`. + +#### Example + +```fortran +{!example/math/example_math_swap.f90!} +``` + ### `gcd` function #### Description diff --git a/example/math/CMakeLists.txt b/example/math/CMakeLists.txt index 0a1411bb9..8b834f348 100644 --- a/example/math/CMakeLists.txt +++ b/example/math/CMakeLists.txt @@ -15,4 +15,5 @@ ADD_EXAMPLE(math_argpi) ADD_EXAMPLE(math_deg2rad) ADD_EXAMPLE(math_rad2deg) ADD_EXAMPLE(math_is_close) +ADD_EXAMPLE(math_swap) ADD_EXAMPLE(meshgrid) diff --git a/example/math/example_math_swap.f90 b/example/math/example_math_swap.f90 new file mode 100644 index 000000000..444e3c713 --- /dev/null +++ b/example/math/example_math_swap.f90 @@ -0,0 +1,33 @@ +program example_math_swap + use stdlib_math, only: swap + implicit none + + block + integer :: x, y + x = 9 + y = 18 + call swap(x,y) + end block + + block + real :: x, y + x = 4.0 + y = 8.0 + call swap(x,y) + end block + + block + real :: x(3), y(3) + x = [1.0,2.0,3.0] + y = [4.0,5.0,6.0] + call swap(x,y) + end block + + block + character(5) :: x, y + x = 'abcde' + y = 'fghij' + call swap(x,y) + end block + +end program example_math_swap \ No newline at end of file diff --git a/src/stdlib_math.fypp b/src/stdlib_math.fypp index 92a946cd9..d94b1ecfd 100644 --- a/src/stdlib_math.fypp +++ b/src/stdlib_math.fypp @@ -8,7 +8,7 @@ module stdlib_math implicit none private - public :: clip, gcd, linspace, logspace + public :: clip, swap, gcd, linspace, logspace public :: EULERS_NUMBER_SP, EULERS_NUMBER_DP #:if WITH_QP public :: EULERS_NUMBER_QP @@ -42,6 +42,17 @@ module stdlib_math #:endfor end interface clip + interface swap + #:for k1, t1 in INT_KINDS_TYPES + REAL_KINDS_TYPES + module procedure :: swap_${k1}$ + #:endfor + #:for k1, t1 in CMPLX_KINDS_TYPES + module procedure :: swap_c${k1}$ + #:endfor + module procedure :: swap_bool + module procedure :: swap_str + end interface + !> Returns the greatest common divisor of two integers !> ([Specification](../page/specs/stdlib_math.html#gcd)) !> @@ -509,5 +520,35 @@ contains end function gcd_${k1}$ #:endfor + + #:for k1, t1 in INT_KINDS_TYPES + REAL_KINDS_TYPES + elemental subroutine swap_${k1}$(lhs, rhs) + ${t1}$, intent(inout) :: lhs, rhs + ${t1}$ :: temp + temp = lhs; lhs = rhs; rhs = temp + end subroutine + + #:endfor + + #:for k1, t1 in CMPLX_KINDS_TYPES + elemental subroutine swap_c${k1}$(lhs, rhs) + ${t1}$, intent(inout) :: lhs, rhs + ${t1}$ :: temp + temp = lhs; lhs = rhs; rhs = temp + end subroutine + + #:endfor + + elemental subroutine swap_bool(lhs, rhs) + logical, intent(inout) :: lhs, rhs + logical :: temp + temp = lhs; lhs = rhs; rhs = temp + end subroutine + + elemental subroutine swap_str(lhs, rhs) + character(1), intent(inout) :: lhs, rhs + character(1) :: temp + temp = lhs; lhs = rhs; rhs = temp + end subroutine end module stdlib_math From 0fa4450f9ab288baa424da8729788f37cb9cf6ea Mon Sep 17 00:00:00 2001 From: jalvesz Date: Tue, 3 Sep 2024 23:51:08 +0200 Subject: [PATCH 02/15] add tests, change string swap --- src/stdlib_math.fypp | 8 ++--- test/math/test_stdlib_math.fypp | 60 ++++++++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/src/stdlib_math.fypp b/src/stdlib_math.fypp index d94b1ecfd..1e41a6781 100644 --- a/src/stdlib_math.fypp +++ b/src/stdlib_math.fypp @@ -545,10 +545,10 @@ contains temp = lhs; lhs = rhs; rhs = temp end subroutine - elemental subroutine swap_str(lhs, rhs) - character(1), intent(inout) :: lhs, rhs - character(1) :: temp - temp = lhs; lhs = rhs; rhs = temp + 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 end module stdlib_math diff --git a/test/math/test_stdlib_math.fypp b/test/math/test_stdlib_math.fypp index 1f64622e4..f38f2d7bb 100644 --- a/test/math/test_stdlib_math.fypp +++ b/test/math/test_stdlib_math.fypp @@ -4,7 +4,7 @@ module test_stdlib_math use testdrive, only : new_unittest, unittest_type, error_type, check, skip_test - use stdlib_math, only: clip, arg, argd, argpi, arange, is_close, all_close, diff, & + use stdlib_math, only: clip, swap, arg, argd, argpi, arange, is_close, all_close, diff, & arange, deg2rad, rad2deg use stdlib_kinds, only: int8, int16, int32, int64, sp, dp, xdp, qp implicit none @@ -38,6 +38,15 @@ contains new_unittest("clip-real-quad", test_clip_rqp), & new_unittest("clip-real-quad-bounds", test_clip_rqp_bounds) & + !> Tests swap + #:for k1, t1 in INT_KINDS_TYPES + REAL_KINDS_TYPES + , new_unittest("swap_${k1}$", test_swap_${k1}$) & + #:endfor + #:for k1, t1 in CMPLX_KINDS_TYPES + , new_unittest("swap_c${k1}$", test_swap_c${k1}$) & + #:endfor + , new_unittest("swap_str", test_swap_str) & + !> Tests for arg/argd/argpi #:for k1 in CMPLX_KINDS , new_unittest("arg-cmplx-${k1}$", test_arg_${k1}$) & @@ -246,6 +255,55 @@ contains end subroutine test_clip_rqp_bounds + #:for k1, t1 in INT_KINDS_TYPES + REAL_KINDS_TYPES + 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 + end subroutine test_swap_${k1}$ + #:endfor + + #:for k1, t1 in CMPLX_KINDS_TYPES + subroutine test_swap_c${k1}$(error) + type(error_type), allocatable, intent(out) :: error + ${t1}$ :: x(3), y(3) + + x = cmplx( [1, 2, 3] , [4, 5, 6] ) + y = cmplx( [4, 5, 6] , [1, 2, 3] ) + + call swap(x,y) + + call check(error, all( x == cmplx( [4, 5, 6] , [1, 2, 3] ) ) ) + if (allocated(error)) return + call check(error, all( y == cmplx( [1, 2, 3] , [4, 5, 6] ) ) ) + if (allocated(error)) return + end subroutine test_swap_c${k1}$ + #:endfor + + subroutine test_swap_str(error) + type(error_type), allocatable, intent(out) :: error + character(5) :: x(2), y(2) + + x = ['abcde','fghij'] + y = ['fghij','abcde'] + + call swap(x,y) + + call check(error, all( x == ['fghij','abcde'] ) ) + if (allocated(error)) return + call check(error, all( y == ['abcde','fghij'] ) ) + if (allocated(error)) return + end subroutine test_swap_str + #:for k1 in CMPLX_KINDS subroutine test_arg_${k1}$(error) type(error_type), allocatable, intent(out) :: error From 0daa4d8903ac5df59af488ea7f3a3d56046bbe9d Mon Sep 17 00:00:00 2001 From: jalvesz Date: Sun, 8 Sep 2024 21:35:13 +0200 Subject: [PATCH 03/15] add self swap tests --- test/math/test_stdlib_math.fypp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/math/test_stdlib_math.fypp b/test/math/test_stdlib_math.fypp index f38f2d7bb..8accb8bb4 100644 --- a/test/math/test_stdlib_math.fypp +++ b/test/math/test_stdlib_math.fypp @@ -269,6 +269,12 @@ contains 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}$ #:endfor @@ -286,6 +292,12 @@ contains if (allocated(error)) return call check(error, all( y == cmplx( [1, 2, 3] , [4, 5, 6] ) ) ) if (allocated(error)) return + + ! check self swap + call swap(x,x) + + call check(error, all( x == cmplx( [4, 5, 6] , [1, 2, 3] ) ) ) + if (allocated(error)) return end subroutine test_swap_c${k1}$ #:endfor @@ -302,6 +314,12 @@ contains if (allocated(error)) return call check(error, all( y == ['abcde','fghij'] ) ) if (allocated(error)) return + + ! check self swap + call swap(x,x) + + call check(error, all( x == ['fghij','abcde'] ) ) + if (allocated(error)) return end subroutine test_swap_str #:for k1 in CMPLX_KINDS From 5a75fa3fa369a7549bf6ec846feec38363e02176 Mon Sep 17 00:00:00 2001 From: jalvesz Date: Mon, 9 Sep 2024 18:57:08 +0200 Subject: [PATCH 04/15] add swap for stdlib string_type --- doc/specs/stdlib_math.md | 4 ++-- example/math/example_math_swap.f90 | 8 ++++++++ src/stdlib_math.fypp | 8 ++++++++ test/math/test_stdlib_math.fypp | 23 +++++++++++++++++++++++ 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/doc/specs/stdlib_math.md b/doc/specs/stdlib_math.md index 71806a9dc..1889f1591 100644 --- a/doc/specs/stdlib_math.md +++ b/doc/specs/stdlib_math.md @@ -82,8 +82,8 @@ Elemental function. #### Argument(s) -`lhs`: scalar or array of any of the intrinsic types `integer`, `real`, `complex`, `logical`, `character` type. This argument is `intent(inout)`. -`rhs`: scalar or array of any of the intrinsic types `integer`, `real`, `complex`, `logical`, `character` type. This argument is `intent(inout)`. +`lhs`: scalar or array of any of the intrinsic types `integer`, `real`, `complex`, `logical`, `character`, `string_type` type. This argument is `intent(inout)`. +`rhs`: scalar or array of any of the intrinsic types `integer`, `real`, `complex`, `logical`, `character`, `string_type` type. This argument is `intent(inout)`. Note: All arguments must have same `type` and same `kind`. diff --git a/example/math/example_math_swap.f90 b/example/math/example_math_swap.f90 index 444e3c713..cba9b37f6 100644 --- a/example/math/example_math_swap.f90 +++ b/example/math/example_math_swap.f90 @@ -30,4 +30,12 @@ program example_math_swap call swap(x,y) end block + block + use stdlib_string_type + type(string_type) :: x, y + x = 'abcde' + y = 'fghij' + call swap(x,y) + end block + end program example_math_swap \ No newline at end of file diff --git a/src/stdlib_math.fypp b/src/stdlib_math.fypp index 1e41a6781..ece280554 100644 --- a/src/stdlib_math.fypp +++ b/src/stdlib_math.fypp @@ -51,6 +51,7 @@ module stdlib_math #:endfor module procedure :: swap_bool module procedure :: swap_str + module procedure :: swap_stt end interface !> Returns the greatest common divisor of two integers @@ -550,5 +551,12 @@ contains character(len=max(len(lhs),len(rhs))) :: temp temp = lhs ; lhs = rhs ; rhs = temp end subroutine + + elemental subroutine swap_stt(lhs,rhs) + use stdlib_string_type + type(string_type), intent(inout) :: lhs, rhs + type(string_type) :: temp + temp = lhs ; lhs = rhs ; rhs = temp + end subroutine end module stdlib_math diff --git a/test/math/test_stdlib_math.fypp b/test/math/test_stdlib_math.fypp index 8accb8bb4..c477ebdbc 100644 --- a/test/math/test_stdlib_math.fypp +++ b/test/math/test_stdlib_math.fypp @@ -46,6 +46,7 @@ contains , new_unittest("swap_c${k1}$", test_swap_c${k1}$) & #:endfor , new_unittest("swap_str", test_swap_str) & + , new_unittest("swap_stt", test_swap_stt) & !> Tests for arg/argd/argpi #:for k1 in CMPLX_KINDS @@ -322,6 +323,28 @@ contains if (allocated(error)) return end subroutine test_swap_str + subroutine test_swap_stt(error) + use stdlib_string_type + type(error_type), allocatable, intent(out) :: error + type(string_type) :: x(2), y(2) + + x = ['abcde','fghij'] + y = ['fghij','abcde'] + + call swap(x,y) + + call check(error, all( x == ['fghij','abcde'] ) ) + if (allocated(error)) return + call check(error, all( y == ['abcde','fghij'] ) ) + if (allocated(error)) return + + ! check self swap + call swap(x,x) + + call check(error, all( x == ['fghij','abcde'] ) ) + if (allocated(error)) return + end subroutine test_swap_stt + #:for k1 in CMPLX_KINDS subroutine test_arg_${k1}$(error) type(error_type), allocatable, intent(out) :: error From e9b9c106e66e0f506959777c2caceca3a5d54a71 Mon Sep 17 00:00:00 2001 From: jalvesz <102541118+jalvesz@users.noreply.github.com> Date: Tue, 10 Sep 2024 09:41:38 +0200 Subject: [PATCH 05/15] Update doc/specs/stdlib_math.md Co-authored-by: Jeremie Vandenplas --- doc/specs/stdlib_math.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/specs/stdlib_math.md b/doc/specs/stdlib_math.md index 1889f1591..96399daeb 100644 --- a/doc/specs/stdlib_math.md +++ b/doc/specs/stdlib_math.md @@ -62,7 +62,7 @@ Here inputs are of type `real` and kind `sp` ``` -### `swap` function +### `swap` subroutine #### Description From e35beca192e3b70b71d37e2d591f59b7c0081753 Mon Sep 17 00:00:00 2001 From: jalvesz <102541118+jalvesz@users.noreply.github.com> Date: Tue, 10 Sep 2024 09:41:50 +0200 Subject: [PATCH 06/15] Update doc/specs/stdlib_math.md Co-authored-by: Jeremie Vandenplas --- doc/specs/stdlib_math.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/specs/stdlib_math.md b/doc/specs/stdlib_math.md index 96399daeb..3e510e26a 100644 --- a/doc/specs/stdlib_math.md +++ b/doc/specs/stdlib_math.md @@ -78,7 +78,7 @@ Experimental #### Class -Elemental function. +Elemental subroutine. #### Argument(s) From 6a30b2ff974aaa9a0a27aa730e0ece321c8b13ac Mon Sep 17 00:00:00 2001 From: jalvesz Date: Tue, 10 Sep 2024 21:33:08 +0200 Subject: [PATCH 07/15] autodoc --- src/stdlib_math.fypp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/stdlib_math.fypp b/src/stdlib_math.fypp index ece280554..c302f5621 100644 --- a/src/stdlib_math.fypp +++ b/src/stdlib_math.fypp @@ -42,6 +42,10 @@ module stdlib_math #:endfor end interface clip + !> Swap the values of the lhs and rhs arguments + !> ([Specification](../page/specs/stdlib_math.html#swap)) + !> + !> Version: experimental interface swap #:for k1, t1 in INT_KINDS_TYPES + REAL_KINDS_TYPES module procedure :: swap_${k1}$ From 1993d628402a8cb9fc90fca78da222f73fcfb393 Mon Sep 17 00:00:00 2001 From: jalvesz Date: Wed, 11 Sep 2024 23:57:46 +0200 Subject: [PATCH 08/15] add bitset support --- doc/specs/stdlib_math.md | 4 +-- example/math/example_math_swap.f90 | 8 ++++++ src/stdlib_math.fypp | 14 +++++++-- test/math/test_stdlib_math.fypp | 46 ++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 4 deletions(-) diff --git a/doc/specs/stdlib_math.md b/doc/specs/stdlib_math.md index 3e510e26a..8fa32084b 100644 --- a/doc/specs/stdlib_math.md +++ b/doc/specs/stdlib_math.md @@ -82,8 +82,8 @@ Elemental subroutine. #### Argument(s) -`lhs`: scalar or array of any of the intrinsic types `integer`, `real`, `complex`, `logical`, `character`, `string_type` type. This argument is `intent(inout)`. -`rhs`: scalar or array of any of the intrinsic types `integer`, `real`, `complex`, `logical`, `character`, `string_type` type. This argument is `intent(inout)`. +`lhs`: scalar or array of any of the intrinsic types `integer`, `real`, `complex`, `logical`, `character`, `string_type`, `bitset` type. This argument is `intent(inout)`. +`rhs`: scalar or array of any of the intrinsic types `integer`, `real`, `complex`, `logical`, `character`, `string_type`, `bitset` type. This argument is `intent(inout)`. Note: All arguments must have same `type` and same `kind`. diff --git a/example/math/example_math_swap.f90 b/example/math/example_math_swap.f90 index cba9b37f6..8a34853c8 100644 --- a/example/math/example_math_swap.f90 +++ b/example/math/example_math_swap.f90 @@ -38,4 +38,12 @@ program example_math_swap call swap(x,y) end block + block + use stdlib_bitsets + type(bitset_64) :: x, y + call x%from_string('0000') + call y%from_string('1111') + call swap(x,y) + end block + end program example_math_swap \ No newline at end of file diff --git a/src/stdlib_math.fypp b/src/stdlib_math.fypp index c302f5621..bc26365d3 100644 --- a/src/stdlib_math.fypp +++ b/src/stdlib_math.fypp @@ -1,7 +1,7 @@ #:include "common.fypp" #:set IR_KINDS_TYPES = INT_KINDS_TYPES + REAL_KINDS_TYPES #:set RC_KINDS_TYPES = REAL_KINDS_TYPES + CMPLX_KINDS_TYPES - +#:set BITSET_KINDS_TYPES = list(zip(BITSET_KINDS, BITSET_TYPES)) module stdlib_math use stdlib_kinds, only: int8, int16, int32, int64, sp, dp, xdp, qp use stdlib_optval, only: optval @@ -47,7 +47,7 @@ module stdlib_math !> !> Version: experimental interface swap - #:for k1, t1 in INT_KINDS_TYPES + REAL_KINDS_TYPES + #:for k1, t1 in INT_KINDS_TYPES + REAL_KINDS_TYPES + BITSET_KINDS_TYPES module procedure :: swap_${k1}$ #:endfor #:for k1, t1 in CMPLX_KINDS_TYPES @@ -562,5 +562,15 @@ contains type(string_type) :: temp temp = lhs ; lhs = rhs ; rhs = temp end subroutine + + #:for k1, t1 in BITSET_KINDS_TYPES + elemental subroutine swap_${k1}$(lhs,rhs) + use stdlib_bitsets + ${t1}$, intent(inout) :: lhs, rhs + ${t1}$ :: temp + temp = lhs ; lhs = rhs ; rhs = temp + end subroutine + + #:endfor end module stdlib_math diff --git a/test/math/test_stdlib_math.fypp b/test/math/test_stdlib_math.fypp index c477ebdbc..834b2f1dd 100644 --- a/test/math/test_stdlib_math.fypp +++ b/test/math/test_stdlib_math.fypp @@ -345,6 +345,52 @@ contains if (allocated(error)) return end subroutine test_swap_stt + subroutine test_swap_bitset_64(error) + use stdlib_bitsets + type(error_type), allocatable, intent(out) :: error + type(bitset_64) :: x, y, u, v + + x = [.true.,.false.,.true.,.false.] + u = x + y = [.false.,.true.,.false.,.true.] + v = y + call swap(x,y) + + call check(error, x == v ) + if (allocated(error)) return + call check(error, y == u ) + if (allocated(error)) return + + ! check self swap + call swap(x,x) + + call check(error, x == v ) + if (allocated(error)) return + end subroutine test_swap_bitset_64 + + subroutine test_swap_bitset_large(error) + use stdlib_bitsets + type(error_type), allocatable, intent(out) :: error + type(bitset_large) :: x, y, u, v + + x = [.true.,.false.,.true.,.false.] + u = x + y = [.false.,.true.,.false.,.true.] + v = y + call swap(x,y) + + call check(error, x == v ) + if (allocated(error)) return + call check(error, y == u ) + if (allocated(error)) return + + ! check self swap + call swap(x,x) + + call check(error, x == v ) + if (allocated(error)) return + end subroutine test_swap_bitset_large + #:for k1 in CMPLX_KINDS subroutine test_arg_${k1}$(error) type(error_type), allocatable, intent(out) :: error From 66175e7ae11cf1b06f57276cd2e42bf6187865f1 Mon Sep 17 00:00:00 2001 From: jalvesz <102541118+jalvesz@users.noreply.github.com> Date: Sun, 15 Sep 2024 21:14:19 +0200 Subject: [PATCH 09/15] Update src/stdlib_math.fypp Co-authored-by: Jeremie Vandenplas --- src/stdlib_math.fypp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stdlib_math.fypp b/src/stdlib_math.fypp index bc26365d3..7959b541a 100644 --- a/src/stdlib_math.fypp +++ b/src/stdlib_math.fypp @@ -557,7 +557,7 @@ contains end subroutine elemental subroutine swap_stt(lhs,rhs) - use stdlib_string_type + use stdlib_string_type, only: string_type type(string_type), intent(inout) :: lhs, rhs type(string_type) :: temp temp = lhs ; lhs = rhs ; rhs = temp From c2a0bada9bf42e0839318d9178369ec008b1f64a Mon Sep 17 00:00:00 2001 From: jalvesz <102541118+jalvesz@users.noreply.github.com> Date: Sun, 15 Sep 2024 21:15:19 +0200 Subject: [PATCH 10/15] Update src/stdlib_math.fypp Co-authored-by: Jeremie Vandenplas --- src/stdlib_math.fypp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stdlib_math.fypp b/src/stdlib_math.fypp index 7959b541a..4a026785d 100644 --- a/src/stdlib_math.fypp +++ b/src/stdlib_math.fypp @@ -43,7 +43,7 @@ module stdlib_math end interface clip !> Swap the values of the lhs and rhs arguments - !> ([Specification](../page/specs/stdlib_math.html#swap)) + !> ([Specification](../page/specs/stdlib_math.html#swap_subroutine)) !> !> Version: experimental interface swap From 7370020e002c4f75b050869bb316b1a6f26b1857 Mon Sep 17 00:00:00 2001 From: jalvesz Date: Sun, 15 Sep 2024 21:39:05 +0200 Subject: [PATCH 11/15] move swap bitset within same fypp loop as for integers and reals --- src/stdlib_math.fypp | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/stdlib_math.fypp b/src/stdlib_math.fypp index 4a026785d..49c63cd51 100644 --- a/src/stdlib_math.fypp +++ b/src/stdlib_math.fypp @@ -5,6 +5,7 @@ module stdlib_math use stdlib_kinds, only: int8, int16, int32, int64, sp, dp, xdp, qp use stdlib_optval, only: optval + use stdlib_bitsets, only: bitset_64, bitset_large implicit none private @@ -526,7 +527,7 @@ contains #:endfor - #:for k1, t1 in INT_KINDS_TYPES + REAL_KINDS_TYPES + #:for k1, t1 in INT_KINDS_TYPES + REAL_KINDS_TYPES + BITSET_KINDS_TYPES elemental subroutine swap_${k1}$(lhs, rhs) ${t1}$, intent(inout) :: lhs, rhs ${t1}$ :: temp @@ -562,15 +563,5 @@ contains type(string_type) :: temp temp = lhs ; lhs = rhs ; rhs = temp end subroutine - - #:for k1, t1 in BITSET_KINDS_TYPES - elemental subroutine swap_${k1}$(lhs,rhs) - use stdlib_bitsets - ${t1}$, intent(inout) :: lhs, rhs - ${t1}$ :: temp - temp = lhs ; lhs = rhs ; rhs = temp - end subroutine - - #:endfor end module stdlib_math From a72bca6fd909dfe642187e3d9788361341be821d Mon Sep 17 00:00:00 2001 From: jalvesz <102541118+jalvesz@users.noreply.github.com> Date: Mon, 16 Sep 2024 17:47:24 +0200 Subject: [PATCH 12/15] Update src/stdlib_math.fypp Co-authored-by: Jeremie Vandenplas --- src/stdlib_math.fypp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stdlib_math.fypp b/src/stdlib_math.fypp index 49c63cd51..31ad628e9 100644 --- a/src/stdlib_math.fypp +++ b/src/stdlib_math.fypp @@ -553,7 +553,7 @@ contains elemental subroutine swap_str(lhs,rhs) character(*), intent(inout) :: lhs, rhs - character(len=max(len(lhs),len(rhs))) :: temp + character(len=:), allocatable :: temp temp = lhs ; lhs = rhs ; rhs = temp end subroutine From 111996497a40fef5b2a5c5d65872518b62a5112d Mon Sep 17 00:00:00 2001 From: jalvesz Date: Wed, 18 Sep 2024 20:18:38 +0200 Subject: [PATCH 13/15] add warning regarding swap on characters --- doc/specs/stdlib_math.md | 7 +++++-- example/math/example_math_swap.f90 | 13 +++++++++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/doc/specs/stdlib_math.md b/doc/specs/stdlib_math.md index 8fa32084b..cfd632456 100644 --- a/doc/specs/stdlib_math.md +++ b/doc/specs/stdlib_math.md @@ -85,9 +85,12 @@ Elemental subroutine. `lhs`: scalar or array of any of the intrinsic types `integer`, `real`, `complex`, `logical`, `character`, `string_type`, `bitset` type. This argument is `intent(inout)`. `rhs`: scalar or array of any of the intrinsic types `integer`, `real`, `complex`, `logical`, `character`, `string_type`, `bitset` type. This argument is `intent(inout)`. -Note: All arguments must have same `type` and same `kind`. +##### Note +All arguments must have same `type` and same `kind`. -#### Example +**WARNING**: For fix size characters with different length, the `swap` subroutine will truncate the longest amongst `lhs` and `rhs`. To avoid truncation it is possible to pass a subsection of the string. + +#### Examples ```fortran {!example/math/example_math_swap.f90!} diff --git a/example/math/example_math_swap.f90 b/example/math/example_math_swap.f90 index 8a34853c8..7c2388b05 100644 --- a/example/math/example_math_swap.f90 +++ b/example/math/example_math_swap.f90 @@ -24,10 +24,15 @@ program example_math_swap end block block - character(5) :: x, y - x = 'abcde' - y = 'fghij' - call swap(x,y) + character(4) :: x + character(6) :: y + x = 'abcd' + y = 'efghij' + call swap(x,y) ! x=efgh, y=abcd + + x = 'abcd' + y = 'efghij' + call swap(x,y(1:4)) ! x=efgh, y=abcdij end block block From 775c8b44f8cf0de7fc4a9d1799247a70ea8ab2f2 Mon Sep 17 00:00:00 2001 From: jalvesz <102541118+jalvesz@users.noreply.github.com> Date: Wed, 18 Sep 2024 20:19:10 +0200 Subject: [PATCH 14/15] Update src/stdlib_math.fypp Co-authored-by: Sebastian Ehlert <28669218+awvwgk@users.noreply.github.com> --- src/stdlib_math.fypp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stdlib_math.fypp b/src/stdlib_math.fypp index 31ad628e9..1b1abb363 100644 --- a/src/stdlib_math.fypp +++ b/src/stdlib_math.fypp @@ -553,7 +553,7 @@ contains elemental subroutine swap_str(lhs,rhs) character(*), intent(inout) :: lhs, rhs - character(len=:), allocatable :: temp + character(len=max(len(lhs), len(rhs))) :: temp temp = lhs ; lhs = rhs ; rhs = temp end subroutine From 7c5763c2b8fa4de5faa1898891366cb9551b2c0d Mon Sep 17 00:00:00 2001 From: jalvesz Date: Sat, 21 Sep 2024 12:35:10 +0200 Subject: [PATCH 15/15] add test for strings with different lengths --- test/math/test_stdlib_math.fypp | 55 ++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/test/math/test_stdlib_math.fypp b/test/math/test_stdlib_math.fypp index 834b2f1dd..1365756b9 100644 --- a/test/math/test_stdlib_math.fypp +++ b/test/math/test_stdlib_math.fypp @@ -304,23 +304,48 @@ contains subroutine test_swap_str(error) type(error_type), allocatable, intent(out) :: error - character(5) :: x(2), y(2) - - x = ['abcde','fghij'] - y = ['fghij','abcde'] + block + character(5) :: x(2), y(2) + + x = ['abcde','fghij'] + y = ['fghij','abcde'] - call swap(x,y) - - call check(error, all( x == ['fghij','abcde'] ) ) - if (allocated(error)) return - call check(error, all( y == ['abcde','fghij'] ) ) - if (allocated(error)) return + call swap(x,y) + + call check(error, all( x == ['fghij','abcde'] ) ) + if (allocated(error)) return + call check(error, all( y == ['abcde','fghij'] ) ) + if (allocated(error)) return - ! check self swap - call swap(x,x) - - call check(error, all( x == ['fghij','abcde'] ) ) - if (allocated(error)) return + ! check self swap + call swap(x,x) + + call check(error, all( x == ['fghij','abcde'] ) ) + if (allocated(error)) return + end block + + block + character(4) :: x + character(6) :: y + + x = 'abcd' + y = 'efghij' + call swap(x,y) + + call check(error, x == 'efgh' ) + if (allocated(error)) return + call check(error, y(1:6) == 'abcd ' ) + if (allocated(error)) return + + x = 'abcd' + y = 'efghij' + call swap(x,y(1:4)) + + call check(error, x == 'efgh' ) + if (allocated(error)) return + call check(error, y == 'abcdij' ) + if (allocated(error)) return + end block end subroutine test_swap_str subroutine test_swap_stt(error)