Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implemented intelligent slice functionality #414

Merged
merged 19 commits into from
Jun 12, 2021
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
90eb9aa
implemented slice function for stdlib_ascii
aman-godara May 23, 2021
e235bc4
added module dependencies of stdlib_math for function slice in Makefi…
aman-godara May 23, 2021
0742ca0
changed names from start to first and end to last
aman-godara May 24, 2021
1a5f78c
forgot to change the dummy argument start to first
aman-godara May 24, 2021
15827d2
shifted slice from stdlib_ascii to stdlib_strings and modified module…
aman-godara May 24, 2021
c7c1e48
removed include_last functionality
aman-godara May 25, 2021
ac607f1
added tests for slice function (with no include_last functionality)
aman-godara May 25, 2021
9d72c69
made complete use of slice interface: added test cases for character …
aman-godara May 25, 2021
a733bc3
documented function slice, corrected documentation of to_title and to…
aman-godara May 26, 2021
fa88905
improved function slice for invalid cases, added new invalid test cases
aman-godara May 27, 2021
42a905d
improved the implementation of last commit fa88905
aman-godara May 28, 2021
ffcb7e4
removed redundant outer loop, improved documentation of slice function
aman-godara May 29, 2021
4598eec
removed dependency of clip function by stdlib_strings.f90
aman-godara May 29, 2021
24d417f
improved documentation and comments for function slice
aman-godara Jun 7, 2021
323bcd9
Add general tester against intrinsic array slice
awvwgk Jun 10, 2021
a895085
Merge pull request #3 from awvwgk/slice
aman-godara Jun 10, 2021
d60dad3
added -inf and +inf concept to make code more intuitive, added descri…
aman-godara Jun 11, 2021
048b638
added the concept of +inf and -inf in documentation
aman-godara Jun 11, 2021
d38e0f4
added fail messages to unit tests
aman-godara Jun 11, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/Makefile.manual
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ stdlib_stats_var.o: \
stdlib_stats_distribution_PRNG.o: \
stdlib_kinds.o \
stdlib_error.o
stdlib_string_type.o: stdlib_ascii.o stdlib_kinds.o
stdlib_strings.o: stdlib_ascii.o stdlib_string_type.o
stdlib_string_type.o: stdlib_ascii.o \
stdlib_kinds.o
stdlib_strings.o: stdlib_ascii.o \
stdlib_string_type.o \
stdlib_math.o
stdlib_math.o: stdlib_kinds.o
72 changes: 72 additions & 0 deletions src/stdlib_strings.f90
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
module stdlib_strings
use stdlib_ascii, only : whitespace
use stdlib_string_type, only : string_type, char, verify
use stdlib_math, only: clip
implicit none
private

public :: strip, chomp
public :: starts_with, ends_with
public :: slice


!> Remove leading and trailing whitespace characters.
Expand Down Expand Up @@ -57,6 +59,14 @@ module stdlib_strings
module procedure :: ends_with_char_string
module procedure :: ends_with_char_char
end interface ends_with

!> Slices the input string to return a new string
!>
!> Version: experimental
interface slice
module procedure :: slice_string
module procedure :: slice_char
end interface slice


contains
Expand Down Expand Up @@ -290,5 +300,67 @@ elemental function ends_with_string_string(string, substring) result(match)

end function ends_with_string_string

!> Slices the region between the input 'first' and 'last' index (both inclusive)
!> of the input 'string' by taking strides of length 'stride'
!> Returns a new string_type object
elemental function slice_string(string, first, last, stride) result(sliced_string)
everythingfunctional marked this conversation as resolved.
Show resolved Hide resolved
type(string_type), intent(in) :: string
integer, intent(in), optional :: first, last, stride
type(string_type) :: sliced_string

sliced_string = string_type(slice(char(string), first, last, stride))

end function slice_string

!> Slices the region between the input 'first' and 'last' index (both inclusive)
!> of the input 'string' by taking strides of length 'stride'
!> Returns a new string
pure function slice_char(string, first, last, stride) result(sliced_string)
character(len=*), intent(in) :: string
integer, intent(in), optional :: first, last, stride
integer :: first_index, last_index, stride_vector, n, i, j
character(len=:), allocatable :: sliced_string

if (len(string) > 0) then
first_index = 1
last_index = len(string)
stride_vector = 1

if (present(stride)) then
if (stride /= 0) then
if (stride < 0) then
first_index = len(string)
last_index = 1
end if
stride_vector = stride
end if
else
if (present(first) .and. present(last)) then
if (last < first) then
stride_vector = -1
end if
end if
end if

if (present(first)) then
first_index = clip(first, 1, len(string))
end if
if (present(last)) then
last_index = clip(last, 1, len(string))
end if

n = int((last_index - first_index) / stride_vector)
allocate(character(len=max(0, n + 1)) :: sliced_string)

j = 1
do i = first_index, last_index, stride_vector
sliced_string(j:j) = string(i:i)
j = j + 1
end do
else
sliced_string = ""
end if
end function slice_char


end module stdlib_strings
42 changes: 42 additions & 0 deletions src/tests/string/test_string_functions.f90
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module test_string_functions
use stdlib_error, only : check
use stdlib_string_type, only : string_type, assignment(=), operator(==), &
to_lower, to_upper, to_title, to_sentence, reverse
use stdlib_strings, only: slice
implicit none

contains
Expand Down Expand Up @@ -52,6 +53,46 @@ subroutine test_reverse_string

end subroutine test_reverse_string

subroutine test_slice_string
type(string_type) :: test_string
character(len=:), allocatable :: test_char
test_string = "abcdefghijklmnopqrstuvwxyz"
test_char = "abcdefghijklmnopqrstuvwxyz"

call check(slice(test_string, 2, 16, 3) == "behkn", &
'function slice failed', warn=.true.)
aman-godara marked this conversation as resolved.
Show resolved Hide resolved
call check(slice(test_char, 15, stride=-1) == "onmlkjihgfedcba", &
'function slice failed', warn=.true.)
call check(slice(test_string, last=22, stride=-1) == "zyxwv", &
'function slice failed', warn=.true.)
call check(slice(test_char, 7, 2) == "gfedcb", &
'function slice failed', warn=.true.)
call check(slice(test_string, 7, 2, 1) == "", &
'function slice failed', warn=.true.)
call check(slice(test_char, 2, 6, -1) == "", &
'function slice failed', warn=.true.)
call check(slice(test_string, stride=-1) == "zyxwvutsrqponmlkjihgfedcba", &
'function slice failed', warn=.true.)
call check(slice(test_string, 7, 7, -4) == "g", &
'function slice failed', warn=.true.)
call check(slice(test_char, 7, 7, 3) == "g", &
'function slice failed', warn=.true.)
call check(slice(test_string, 7, 7, 3) == "g", &
'function slice failed', warn=.true.)
call check(slice(test_char, 7, -10) == "gfedcba", &
'function slice failed', warn=.true.)
call check(slice(test_string, 500, 22) == "zyxwv", &
'function slice failed', warn=.true.)

test_string = ""
test_char = ""
call check(slice(test_string, 2, 16, 3) == "", &
'function slice failed', warn=.true.)
call check(slice(test_char, 2, 16, 3) == "", &
'function slice failed', warn=.true.)

end subroutine test_slice_string

end module test_string_functions


Expand All @@ -64,5 +105,6 @@ program tester
call test_to_title_string
call test_to_sentence_string
call test_reverse_string
call test_slice_string

end program tester