diff --git a/README.md b/README.md index d82cf2897..5873bbd57 100644 --- a/README.md +++ b/README.md @@ -138,7 +138,7 @@ To test your build, run the test suite after the build has finished with cmake --build build --target test ``` -Please report failing tests on our [issue tracker](https://github.com/fortran-lang/stdlib/issues/new/choose) including details on the compiler used, the operating system and platform architecture. +Please report failing tests on our [issue tracker](https://github.com/fortran-lang/stdlib/issues/new/choose) including details of the compiler used, the operating system and platform architecture. To install the project to the declared prefix run diff --git a/doc/specs/stdlib_string_type.md b/doc/specs/stdlib_string_type.md index adbf7483e..63c38ccf4 100644 --- a/doc/specs/stdlib_string_type.md +++ b/doc/specs/stdlib_string_type.md @@ -1041,6 +1041,187 @@ end program demo ``` + +### To\_lower function + +#### Description + +Returns a new string_type instance which holds the lowercase version of the character sequence hold by the input string. + +#### Syntax + +`lowercase_string = [[stdlib_string_type(module): to_lower(interface)]] (string)` + +#### Status + +Experimental + +#### Class + +Elemental function. + +#### Argument + +`string`: Instance of `string_type`. This argument is `intent(in)`. + +#### Result Value + +The Result is a scalar `string_type` value. + +#### Example + +```fortran +program demo + use stdlib_string_type + implicit none + type(string_type) :: string, lowercase_string + + string = "Lowercase This String" + ! string <-- "Lowercase This String" + + lowercase_string = to_lower(string) + ! string <-- "Lowercase This String" + ! lowercase_string <-- "lowercase this string" +end program demo +``` + + + +### To\_upper function + +#### Description + +Returns a new string_type instance which holds the uppercase version of the character sequence hold by the input string. + +#### Syntax + +`uppercase_string = [[stdlib_string_type(module): to_upper(interface)]] (string)` + +#### Status + +Experimental + +#### Class + +Elemental function. + +#### Argument + +`string`: Instance of `string_type`. This argument is `intent(in)`. + +#### Result Value + +The Result is a scalar `string_type` value. + +#### Example + +```fortran +program demo + use stdlib_string_type + implicit none + type(string_type) :: string, uppercase_string + + string = "Uppercase This String" + ! string <-- "Uppercase This String" + + uppercase_string = to_upper(string) + ! string <-- "Uppercase This String" + ! uppercase_string <-- "UPPERCASE THIS STRING" +end program demo +``` + + + +### To\_title function + +#### Description + +Returns a new string_type instance which holds the titlecase (or capitalized) version of the character sequence hold by the input string. +Capitalized version: The first alphabetical character of the input character sequence is transformed to uppercase unless it +follows a numeral and the rest of the characters in the sequence are transformed to lowercase. + +#### Syntax + +`titlecase_string = [[stdlib_string_type(module): to_title(interface)]] (string)` + +#### Status + +Experimental + +#### Class + +Elemental function. + +#### Argument + +`string`: Instance of `string_type`. This argument is `intent(in)`. + +#### Result Value + +The Result is a scalar `string_type` value. + +#### Example + +```fortran +program demo + use stdlib_string_type + implicit none + type(string_type) :: string, titlecase_string + + string = "Titlecase This String" + ! string <-- "Titlecase This String" + + titlecase_string = to_title(string) + ! string <-- "Titlecase This String" + ! titlecase_string <-- "Titlecase this string" +end program demo +``` + + +### Reverse function + +#### Description + +Returns a new string_type instance which holds the reversed version of the character sequence hold by the input string. + +#### Syntax + +`reverse_string = [[stdlib_string_type(module): reverse(interface)]] (string)` + +#### Status + +Experimental + +#### Class + +Elemental function. + +#### Argument + +`string`: Instance of `string_type`. This argument is `intent(in)`. + +#### Result Value + +The Result is a scalar `string_type` value. + +#### Example + +```fortran +program demo + use stdlib_string_type + implicit none + type(string_type) :: string, reverse_string + + string = "Reverse This String" + ! string <-- "Reverse This String" + + reverse_string = reverse(string) + ! string <-- "Reverse This String" + ! reverse_string <-- "gnirtS sihT esreveR" +end program demo +``` + + ### Comparison operator greater diff --git a/src/Makefile.manual b/src/Makefile.manual index 804b04272..b59340b8c 100644 --- a/src/Makefile.manual +++ b/src/Makefile.manual @@ -109,3 +109,4 @@ stdlib_stats_var.o: \ stdlib_stats_distribution_PRNG.o: \ stdlib_kinds.o \ stdlib_error.o +stdlib_string_type.o: stdlib_ascii.o \ No newline at end of file diff --git a/src/stdlib_ascii.f90 b/src/stdlib_ascii.f90 index a9111888a..e446f29e2 100644 --- a/src/stdlib_ascii.f90 +++ b/src/stdlib_ascii.f90 @@ -64,6 +64,36 @@ module stdlib_ascii character(len=*), public, parameter :: lowercase = letters(27:) !! a .. z character(len=*), public, parameter :: whitespace = " "//TAB//VT//CR//LF//FF !! ASCII _whitespace + + !> Returns a new character sequence which is the lower case + !> version of the input character sequence + !> This method is pure and returns a character sequence + interface to_lower + module procedure :: to_lower + end interface to_lower + + !> Returns a new character sequence which is the upper case + !> version of the input character sequence + !> This method is pure and returns a character sequence + interface to_upper + module procedure :: to_upper + end interface to_upper + + !> Returns a new character sequence which is the title case + !> version of the input character sequence + !> This method is pure and returns a character sequence + interface to_title + module procedure :: to_title + end interface to_title + + !> Returns a new character sequence which is reverse of + !> the input charater sequence + !> This method is pure and returns a character sequence + interface reverse + module procedure :: reverse + end interface reverse + + contains !> Checks whether `c` is an ASCII letter (A .. Z, a .. z). diff --git a/src/stdlib_string_type.f90 b/src/stdlib_string_type.f90 index ebc5f1485..2b46a5de9 100644 --- a/src/stdlib_string_type.f90 +++ b/src/stdlib_string_type.f90 @@ -12,12 +12,16 @@ !> !> The specification of this module is available [here](../page/specs/stdlib_string_type.html). module stdlib_string_type + use stdlib_ascii, only: to_lower_ => to_lower, to_upper_ => to_upper, & + to_title_ => to_title, reverse_ => reverse + implicit none private public :: string_type public :: len, len_trim, trim, index, scan, verify, repeat, adjustr, adjustl public :: lgt, lge, llt, lle, char, ichar, iachar + public :: to_lower, to_upper, to_title, reverse public :: assignment(=) public :: operator(>), operator(>=), operator(<), operator(<=) public :: operator(==), operator(/=), operator(//) @@ -89,6 +93,38 @@ module stdlib_string_type module procedure :: repeat_string end interface repeat + !> Returns the lowercase version of the character sequence hold by the input string + !> + !> This method is Elemental and returns a new string_type instance which holds this + !> lowercase character sequence + interface to_lower + module procedure :: to_lower_string + end interface to_lower + + !> Returns the uppercase version of the character sequence hold by the input string + !> + !> This method is Elemental and returns a new string_type instance which holds this + !> uppercase character sequence + interface to_upper + module procedure :: to_upper_string + end interface to_upper + + !> Returns the titlecase version of the character sequence hold by the input string + !> + !> This method is Elemental and returns a new string_type instance which holds this + !> titlecase character sequence + interface to_title + module procedure :: to_title_string + end interface to_title + + !> Reverses the character sequence hold by the input string + !> + !> This method is Elemental and returns a new string_type instance which holds this + !> reverse character sequence + interface reverse + module procedure :: reverse_string + end interface reverse + !> Return the character sequence represented by the string. !> !> This method is elemental and returns a scalar character value. @@ -447,6 +483,46 @@ elemental function repeat_string(string, ncopies) result(repeated_string) end function repeat_string + !> Convert the character sequence hold by the input string to lower case + elemental function to_lower_string(string) result(lowercase_string) + type(string_type), intent(in) :: string + type(string_type) :: lowercase_string + + lowercase_string%raw = to_lower_(maybe(string)) + + end function to_lower_string + + + !> Convert the character sequence hold by the input string to upper case + elemental function to_upper_string(string) result(uppercase_string) + type(string_type), intent(in) :: string + type(string_type) :: uppercase_string + + uppercase_string%raw = to_upper_(maybe(string)) + + end function to_upper_string + + + !> Convert the character sequence hold by the input string to title case + elemental function to_title_string(string) result(titlecase_string) + type(string_type), intent(in) :: string + type(string_type) :: titlecase_string + + titlecase_string%raw = to_title_(maybe(string)) + + end function to_title_string + + + !> Reverse the character sequence hold by the input string + elemental function reverse_string(string) result(reversed_string) + type(string_type), intent(in) :: string + type(string_type) :: reversed_string + + reversed_string%raw = reverse_(maybe(string)) + + end function reverse_string + + !> Position of a sequence of character within a character sequence. !> In this version both character sequences are represented by a string. elemental function index_string_string(string, substring, back) result(pos) diff --git a/src/tests/string/test_string_functions.f90 b/src/tests/string/test_string_functions.f90 new file mode 100644 index 000000000..7adeffa17 --- /dev/null +++ b/src/tests/string/test_string_functions.f90 @@ -0,0 +1,58 @@ +! SPDX-Identifier: MIT +module test_string_functions + use stdlib_error, only : check + use stdlib_string_type, only : string_type, assignment(=), operator(==), & + to_lower, to_upper, to_title, reverse + implicit none + +contains + + subroutine test_to_lower_string + type(string_type) :: test_string, compare_string + test_string = "To_LoWEr !$%-az09AZ" + compare_string = "to_lower !$%-az09az" + + call check(to_lower(test_string) == compare_string) + + end subroutine test_to_lower_string + + subroutine test_to_upper_string + type(string_type) :: test_string, compare_string + test_string = "To_UpPeR !$%-az09AZ" + compare_string = "TO_UPPER !$%-AZ09AZ" + + call check(to_upper(test_string) == compare_string) + + end subroutine test_to_upper_string + + subroutine test_to_title_string + type(string_type) :: test_string, compare_string + test_string = "_#To tiTlE !$%-az09AZ" + compare_string = "_#To title !$%-a09az" + + call check(to_title(test_string) == compare_string) + + end subroutine test_to_title_string + + subroutine test_reverse_string + type(string_type) :: test_string, compare_string + test_string = "_To ReVerSe !$%-az09AZ " + compare_string = " ZA90za-%$! eSreVeR oT_" + + call check(reverse(test_string) == compare_string) + + end subroutine test_reverse_string + +end module test_string_functions + + +program tester + use test_string_functions + implicit none + + call test_to_lower_string + call test_to_upper_string + call test_to_title_string + call test_reverse_string + +end program tester