From 405e06f12df8ac788591751f2414c8faa0420002 Mon Sep 17 00:00:00 2001 From: arjenmarkus Date: Wed, 3 Feb 2021 21:39:34 +0100 Subject: [PATCH 01/40] Add module for list of strings The API for the module to manipulate lists of strings has been discussed and this has resulted in the current implementation --- doc/specs/stdlib_stringlist.md | 487 +++++++++ src/stdlib_stringlist.f90 | 996 +++++++++++++++++++ src/tests/stringlist/CMakeLists.txt | 4 + src/tests/stringlist/test_delete.f90 | 57 ++ src/tests/stringlist/test_find.f90 | 72 ++ src/tests/stringlist/test_insert.f90 | 91 ++ src/tests/stringlist/test_replace_append.f90 | 88 ++ 7 files changed, 1795 insertions(+) create mode 100644 doc/specs/stdlib_stringlist.md create mode 100644 src/stdlib_stringlist.f90 create mode 100644 src/tests/stringlist/CMakeLists.txt create mode 100644 src/tests/stringlist/test_delete.f90 create mode 100644 src/tests/stringlist/test_find.f90 create mode 100644 src/tests/stringlist/test_insert.f90 create mode 100644 src/tests/stringlist/test_replace_append.f90 diff --git a/doc/specs/stdlib_stringlist.md b/doc/specs/stdlib_stringlist.md new file mode 100644 index 000000000..a214ce565 --- /dev/null +++ b/doc/specs/stdlib_stringlist.md @@ -0,0 +1,487 @@ +--- +title: stringlist +--- +# Lists of strings + +[TOC] + +## Introduction + +Fortran has supported variable-length strings since the 2003 standard, +but it does not have a native type to handle collections of strings of +different lengths. Such collections are quite useful though and the +language allows us to define a derived type that can handle such +collections. + +The `stdlib_stringlist` module defines a derived type that is capable of +storing a list of strings and of manipulating them. + +Methods include: + +* inserting strings at a given position +* replacing strings at a given position +* deleting a single string or a range of strings +* retrieving a string or a range of strings at a given position +* finding the position of a particular string or a string which contains some substring +* sorting the list + +## Positions in a list of strings + +The module implements what are effectively infinitely long lists: a position is +represented as a positive integer, but there is no "out-of-bound" index. That is, +the following piece of code will simply work: + +```fortran +type(stringlist_type) :: list + +! Add two strings ... +call list%insert( list_head, "The first string" ) +call list%insert( 20, "The last string" ) + +write(*,*) 'The last: ', list%get(list_end) +write(*,*) 'Beyond that: ', list%get(30) +``` +The special position `list_head` represents *the first element*, though a value +of 1 is equivalent. Likewise, the special position `list_end` represents the position +of the *last* element and the position `list_after_end` the position directly after +the last element. You can use these positions to insert a string before the current +first string that is already in the list or to insert after the last string that +has been inserted. + +If you specify a position beyond the last, the `list%get()` method simply returns an empty +string. The same holds for *zero* or *negative* indices. + +For inserting one or more elements, a *zero* or *negative* index is interpreted to mean the first, +an index beyond the last as the one *after* the last - this means effectively that the element is appended. + +If you do: + +```fortran +call list%insert( 1, 'The first string' ) +call list%insert( -10, 'A new first string' ) +``` + +the second inserted string will become the string at the *first* position (1) and all other strings +are shifted by one: + +```none +element 1: 'A new first string' +element 2: 'The first string' +element 3: ... +``` + +If you need the last but one string, you can do so in this way: + +```fortran +write(*,*) 'The last but one: ', list%get(list_end-1) +``` + +So, it is possible to do simple arithmetic. + + +## The derived type: stringlist_type + +### Status + +Experimental + +### Description + +The type holds a small number of components and gives access to a number of procedures, +some of which are implemented as subroutines, others as functions or as operations. + + +### Public `stringlist_type` methods + +The following methods are defined: + +Method | Class | Description +---------------------|------------|------------ +[`delete`](./stdlib_stringlist.html#delete-delete_one_or_more_strings) | Subroutine | Delete one or more strings from the list +[`destroy`](./stdlib_stringlist.html#destroy_destroy_all_strings_in_the_list) | Subroutine | Destroy the contents of the list +[`get`](./stdlib_stringlist.html#get-get_a_single_string_from_a_list) | Function | Get a string from a particular position +[`index`](./stdlib_stringlist.html#index-find_the_index_of_a_particular_string_in_the_list) | Function | Find the index of a string in a list +[`index_sub`](./stdlib_stringlist.html#index_sub-find_the_index_of_a_particular_string_containing_the_given_substring) | Function | Find the index of a string containing a partilcar substring +[`insert`](./stdlib_stringlist.html#insert-insert_one_or_more_strings_after_a_given_position) | Subroutine | Insert a string or a list after a given position +[`length`](./stdlib_stringlist.html#length-return_the_length_of_the_list) | Function | Return the index of the last set position +[`range`](./stdlib_stringlist.html#range-retrieve_a_range_of_string_from_the_list) | Function | Retrieve a range of strings from the list +[`replace`](./stdlib_stringlist.html#replace-replace_one_or_more_strings_between_two_given_positions) | Subroutine | Replace one or more stringa between two positions +[`sort`](./stdlib_stringlist.html#sort-return_a_sorted_list) | Function | Sort the list and return the result as a new list +[`=`](./stdlib_stringlist.html#assign-copy_the_contents_of_a_list) | Assignment | Copy a list +[`//`](./stdlib_stringlist.html#//-concatenate_a_list_with_one_or_more_strings) | Operation | Concatenate a list with a string or concatenate two lists + + +## Details of the methods + +### `delete` - delete one or more strings + +#### Status + +Experimental + +#### Description + +Delete one or more strings from the list via a given position or positions. + +#### Syntax + +`call list % [[stringlist_type(type):delete(bound)]]( first [, last] )` + +#### Class + +Subroutine + +#### Arguments + +`list`: the stringlist variable from which to delete one or more strings + +`first`: the index of the first string to be deleted + +`last` (optional): the index of the last string to be deleted. If left out, only one string is deleted. +If the value is lower than that of `first`, the range is considered to be empty and nothing is deleted. + + +### `destroy` - destroy all strings in the list + +#### Status + +Experimental + +#### Description + +Destroy the entire contents of the list. As the variable holding the list is simply a derived type, the variable +itself is not destroyed. + +#### Syntax + +`call list % [[stringlist_type(type):destroy(bound)]]` + +#### Class + +Subroutine + +#### Arguments + +`list`: the stringlist variable from which to delete all strings + + +### `get` - get a single string from the list + +#### Status + +Experimental + +#### Description + +Get the string at the given position. + +#### Syntax + +`string = list % [[stringlist_type(type):get(bound) ( idx )]]` + +#### Class + +Function + +#### Arguments + +`list`: the stringlist variable to retrieve a string from + +`idx`: the index of the string to be retrieved (see [`the section on positions`](./stdlib_stringlist.html#position-in-a-list-of-strings) + +#### Result value + +A copy of the string stored at the indicated position. + + +### `index` - find the index of a particular string in the list + +#### Status + +Experimental + +#### Description + +Get the position of the first stored string that matches the given string, if `back` is not present or false. If `back` is +false, return the position of the last stored string that matches. Note that trailing blanks are ignored. + +#### Syntax + +`idx = list % [[stringlist_type(type):index(bound) ( string, back )]]` + +#### Class + +Function + +#### Arguments + +`list`: the stringlist variable to retrieve a string from + +`string`: the string to be found in the list + +`back` (optional): logical argument indicating the first occurrence should be returned (`false`) or the last (`true`) + +#### Result value + +The result is either the index of the string in the list or -1 if the string was not found + +#### Example + +Because trailing blanks are ignored, the following calls will give the same result: + +```fortran + write(*,*) list%index( 'A' ) + write(*,*) list%index( 'A ' ) +``` + + +### `index_sub` - find the index of a string containing the given substring in the list + +#### Status + +Experimental + +#### Description + +Get the position of the first stored string that contains the given substring, if `back` is not present or false. If `back` is +false, return the position of the last stored string that contains it. + +#### Syntax + +`idx = list % [[stringlist_type(type):index_sub(bound) ( substring, back )]]` + +#### Class + +Function + +#### Arguments + +`list`: the stringlist variable to retrieve a string from + +`substring`: the substring in question + +`back` (optional): logical argument indicating the first occurrence should be returned (`false`) or the last (`true`) + +#### Result value + +The result is either the index of the string in the list or -1 if the string was not found + + +### `insert` - insert one or more strings after a given position + +#### Status + +Experimental + +#### Description + +Insert one or more strings at a given position. The position may be anything as explained in the section on positions. +A single string may be inserted, another list of strings or a plain array of strings. In all cases trailing blanks, if any, +are retained. + +#### Syntax + +`idx = list % [[stringlist_type(type):insert(bound) ( idx, string )]]` + +#### Class + +Subroutine + +#### Arguments + +`list`: the stringlist variable to insert the string(s) into + +`idx`: the position after which the strings should be inserted + +`string`: the string to be inserted, a list of strings or a plain array of strings + + +### `length` - return the length of the list + +#### Status + +Experimental + +#### Description + +Return the length of the list, defined as the highest index for which a string has been assigned. You can place strings +in any position without needing to fill in the intervening positions. + +#### Syntax + +`length = list % [[stringlist_type(type):length(bound) ()]]` + +#### Class + +Function + +#### Arguments + +`list`: the stringlist variable to retrieve the length from + +#### Result value + +Returns the highest index of a string that has been set. + + + +### `range` - retrieve a range of strings from the list + +#### Status + +Experimental + +#### Description + +Retrieve the strings occurring between the given positions as a new list. + +#### Syntax + +`rangelist = list % [[stringlist_type(type):range(bound) ( first, last )]]` + +#### Class + +Function + +#### Arguments + +`list`: the stringlist variable to insert the string(s) into + +`first`: the position of the first string to be retrieved + +`last`: the position of the last string to be retrieved + +#### Result value + +The result is a new list containing all the strings that appear from the first to the last position, inclusively. + + + +### `replace` - replace one or more strings between two given positions + +#### Status + +Experimental + +#### Description + +Replace one or more strings between two given positions. The new strings may be given as a single string, a list of +strings or a plain array. + +#### Syntax + +`call list % [[stringlist_type(type):replace(bound) ( first, last, string )]]` + +#### Class + +Subroutine + +#### Arguments + +`list`: the stringlist variable to replace the string(s) in + + +`first`: the position of the first string to be retrieved + +`last`: the position of the last string to be retrieved. If only one string needs to be replaced by another string, +then this argument can be left out. + +`string`: the string to be inserted, a list of strings or a plain array of strings + + + +### `sort` - return a sorted list + +#### Status + +Experimental + +#### Description + +Create a new list consisting of the sorted strings of the given list. The strings are sorted according to ASCII, either +in ascending order or descending order. + +#### Syntax + +`sortedlist = list % [[stringlist_type(type):sort(bound) ( ascending )]]` + +#### Class + +Subroutine + +#### Arguments + +`list`: the stringlist variable of which the contents should be copied + +`ascending` (optional): if not present or true, sort the list in ascending order, otherwise descending + +#### Result value + +The contents of the given list is sorted and then stored in the new list. + + +### `=` - copy the contents of a list + +#### Status + +Experimental + +#### Description + +Copy an existing list to a new one. The original list remains unchanged. + +#### Syntax + +`copylist = list` + +#### Class + +Assignment + +#### Operands + +`list`: the stringlist variable to be copied + + + +### `//` - concatenate a list with one or more strings + +#### Status + +Experimental + +#### Description + +Concatenate a list with a string, a list of strings or a plain array + +#### Syntax + +`concatenatedlist = list // string` + +`concatenatedlist = string // list` + +#### Class + +Assignment + +#### Operands + +`list`: the stringlist variable to be concatenated + +`string`: the string to be concatenated, a list of strings or a plain array of strings + +#### Result value + +A stringlist that contains the concatenation of the two operands. + + + +## TODO + +Additional methods: + +filter + +map + +Suggestions from the discussion diff --git a/src/stdlib_stringlist.f90 b/src/stdlib_stringlist.f90 new file mode 100644 index 000000000..4dfb192ed --- /dev/null +++ b/src/stdlib_stringlist.f90 @@ -0,0 +1,996 @@ +! stdlib_stringlist.f90 -- +! Module for storing and manipulating lists of strings +! The strings may have arbitrary lengths, not necessarily the same +! +! Note: very preliminary +! +! TODO: +! insert( list_end, ... ) in an empty list? +! concatenate two string lists +! +! Not implemented yet: +! insert a list or an array of character strings +! replace a string, list or an array of character strings +! concatenate a list with another list or an array +! +! Limited to implemented routines +! +module stdlib_stringlist + implicit none + + private + public :: stringlist_type + public :: operator(//) + public :: operator(+) + public :: operator(-) + public :: list_end + + type stringlist_index_type + private + logical :: head + integer :: offset + end type stringlist_index_type + + type(stringlist_index_type), parameter :: list_head = stringlist_index_type( .true., 1 ) + type(stringlist_index_type), parameter :: list_end = stringlist_index_type( .false., 0 ) + type(stringlist_index_type), parameter :: list_after_end = stringlist_index_type( .false., 1 ) + + interface operator(+) + module procedure stringlist_index_add + end interface + + interface operator(-) + module procedure stringlist_index_subtract + end interface + + type string_type + character(len=:), allocatable :: value + end type string_type + + type stringlist_type + private + integer :: size = 0 + type(string_type), dimension(:), allocatable :: string + contains + private + procedure, public :: destroy => destroy_list + procedure :: insert_string_idx => insert_string_idx_wrap + procedure :: insert_string_int => insert_string_int_impl + procedure :: insert_stringlist_idx => insert_stringlist_idx_wrap + procedure :: insert_stringlist_int => insert_stringlist_int_impl + procedure :: insert_stringarray_idx => insert_stringarray_idx_wrap + procedure :: insert_stringarray_int => insert_stringarray_int_impl + generic, public :: insert => insert_string_int, insert_string_idx, & + insert_stringlist_int, insert_stringlist_idx, & + insert_stringarray_int, insert_stringarray_idx + procedure :: get_string_int => get_string_int_impl + procedure :: get_string_idx => get_string_idx_wrap + generic, public :: get => get_string_int, get_string_idx + procedure, public :: length => length_list + procedure, public :: sort => sort_list + procedure, public :: index => index_of_string + procedure, public :: index_sub => index_of_substring + procedure :: delete_strings_int_int => delete_strings_int_int_impl + procedure :: delete_strings_idx_int => delete_strings_idx_int_wrap + procedure :: delete_strings_int_idx => delete_strings_int_idx_wrap + procedure :: delete_strings_idx_idx => delete_strings_idx_idx_wrap + generic, public :: delete => delete_strings_int_int, delete_strings_idx_int, & + delete_strings_int_idx, delete_strings_idx_idx + procedure :: range_list_int_int => range_list_int_int_impl + procedure :: range_list_idx_int => range_list_idx_int_wrap + procedure :: range_list_int_idx => range_list_int_idx_wrap + procedure :: range_list_idx_idx => range_list_idx_idx_wrap + generic, public :: range => range_list_int_int, range_list_idx_idx, & + range_list_int_idx, range_list_idx_int + procedure :: replace_string_idx => replace_string_idx_wrap + procedure :: replace_string_int => replace_string_int_impl + procedure :: replace_string_int_int => replace_string_int_int_impl + procedure :: replace_stringarray_int_int => replace_stringarray_int_int_impl + procedure :: replace_stringlist_int_int => replace_stringlist_int_int_impl + procedure :: replace_string_idx_idx => replace_string_idx_idx_wrap + procedure :: replace_stringarray_idx_idx => replace_stringarray_idx_idx_wrap + procedure :: replace_stringlist_idx_idx => replace_stringlist_idx_idx_wrap + procedure :: replace_string_idx_int => replace_string_idx_int_wrap + procedure :: replace_stringarray_idx_int => replace_stringarray_idx_int_wrap + procedure :: replace_stringlist_idx_int => replace_stringlist_idx_int_wrap + procedure :: replace_string_int_idx => replace_string_int_idx_wrap + procedure :: replace_stringarray_int_idx => replace_stringarray_int_idx_wrap + procedure :: replace_stringlist_int_idx => replace_stringlist_int_idx_wrap + generic, public :: replace => replace_string_int_int, replace_stringarray_int_int, & + replace_stringlist_int_int, & + replace_string_idx, replace_string_int, & + replace_string_idx_idx, replace_stringarray_idx_idx, & + replace_stringlist_idx_idx, & + replace_string_idx_int, replace_stringarray_idx_int, & + replace_stringlist_idx_int, & + replace_string_int_idx, replace_stringarray_int_idx, & + replace_stringlist_int_idx + end type stringlist_type + + interface operator(<) + module procedure string_lower + end interface + + interface operator(>) + module procedure string_greater + end interface + + interface operator(==) + module procedure string_equal + end interface + + interface operator(//) + module procedure append_string + module procedure prepend_string + module procedure append_stringlist + module procedure append_stringarray + module procedure prepend_stringarray + end interface +contains + +! stringlist_index_add -- +! Add an integer offset to the special index +! +! Arguments: +! index Special index +! offset Offset to be added +! +function stringlist_index_add( index, offset ) + type(stringlist_index_type), intent(in) :: index + integer, intent(in) :: offset + + type(stringlist_index_type) :: stringlist_index_add + + stringlist_index_add = index + stringlist_index_add%offset = stringlist_index_add%offset + offset +end function stringlist_index_add + +! stringlist_index_substract -- +! Subtract an integer offset to the special index +! +! Arguments: +! index Special index +! offset Offset to be substracted +! +function stringlist_index_subtract( index, offset ) + type(stringlist_index_type), intent(in) :: index + integer, intent(in) :: offset + + type(stringlist_index_type) :: stringlist_index_subtract + + stringlist_index_subtract = index + stringlist_index_subtract%offset = stringlist_index_subtract%offset - offset +end function stringlist_index_subtract + +! compare string_type derived types +! Required by sorting functions +! +elemental logical function string_lower( string1, string2 ) + type(string_type), intent(in) :: string1 + type(string_type), intent(in) :: string2 + + string_lower = string1%value < string2%value +end function string_lower + +elemental logical function string_greater( string1, string2 ) + type(string_type), intent(in) :: string1 + type(string_type), intent(in) :: string2 + + string_greater = string1%value > string2%value +end function string_greater + +elemental logical function string_equal( string1, string2 ) + type(string_type), intent(in) :: string1 + type(string_type), intent(in) :: string2 + + string_equal = string1%value == string2%value +end function string_equal + +function append_string( list, string ) + type(stringlist_type), intent(in) :: list + character(len=*), intent(in) :: string + type(stringlist_type) :: append_string + + append_string = list + call append_string%insert( list_after_end, string ) +end function append_string + +function prepend_string( string, list ) + character(len=*), intent(in) :: string + type(stringlist_type), intent(in) :: list + type(stringlist_type) :: prepend_string + + prepend_string = list + call prepend_string%insert( list_head, string ) +end function prepend_string + +function append_stringlist( slist, list ) + type(stringlist_type), intent(in) :: list + type(stringlist_type), intent(in) :: slist + type(stringlist_type) :: append_stringlist + + append_stringlist = list + call append_stringlist%insert( list_after_end, slist ) +end function append_stringlist + +function append_stringarray( list, sarray ) + type(stringlist_type), intent(in) :: list + character(len=*), dimension(:), intent(in) :: sarray + type(stringlist_type) :: append_stringarray + + append_stringarray = list + call append_stringarray%insert( list_after_end, sarray ) +end function append_stringarray + +function prepend_stringarray( sarray, list ) + character(len=*), dimension(:), intent(in) :: sarray + type(stringlist_type), intent(in) :: list + type(stringlist_type) :: prepend_stringarray + + prepend_stringarray = list + call prepend_stringarray%insert( list_head, sarray ) +end function prepend_stringarray + + +! destroy_list -- +! Destroy the contetns of the list +! +! Arguments: +! list The list of strings in question +! +subroutine destroy_list( list ) + class(stringlist_type), intent(inout) :: list + + list%size = 0 + deallocate( list%string ) +end subroutine destroy_list + +! length_list -- +! Return the size (length) of the list +! +! Arguments: +! list The list of strings to retrieve the string from +! +integer function length_list( list ) + class(stringlist_type), intent(in) :: list + + length_list = list%size +end function length_list + +! insert_string -- +! Insert a new string (or an array of strings of another list) into the list +! +! Arguments: +! list The list of strings where the new string(s) should be inserted +! idx Index at which to insert the string +! string The string in question +! +subroutine insert_string_idx_wrap( list, idx, string ) + class(stringlist_type), intent(inout) :: list + type(stringlist_index_type), intent(in) :: idx + character(len=*), intent(in) :: string + + integer :: idxabs + + idxabs = merge( idx%offset, list%size + idx%offset, idx%head ) + + call list%insert( idxabs, string ) +end subroutine insert_string_idx_wrap + +subroutine insert_stringlist_idx_wrap( list, idx, slist ) + class(stringlist_type), intent(inout) :: list + type(stringlist_index_type), intent(in) :: idx + class(stringlist_type), intent(in) :: slist + + integer :: idxabs + + idxabs = merge( idx%offset, list%size + idx%offset, idx%head ) + + call list%insert( idxabs, slist ) +end subroutine insert_stringlist_idx_wrap + +subroutine insert_stringarray_idx_wrap( list, idx, sarray ) + class(stringlist_type), intent(inout) :: list + type(stringlist_index_type), intent(in) :: idx + character(len=*), dimension(:), intent(in) :: sarray + + integer :: idxabs + + idxabs = merge( idx%offset, list%size + idx%offset, idx%head ) + + call list%insert( idxabs, sarray ) +end subroutine insert_stringarray_idx_wrap + +! insert_empty_positions +! Insert a number of positions for new strings +! +! Arguments: +! list The list of strings where the empty positions should be inserted +! idxn Index at which the positions should be inserted +! number Number of positions +! +subroutine insert_empty_positions( list, idxn, number ) + class(stringlist_type), intent(inout) :: list + integer, intent(inout) :: idxn + integer, intent(in) :: number + + integer :: i, inew + integer :: lastidx + type(string_type), dimension(:), allocatable :: new_string + + ! + ! Clip the index between 1 and size+1 + ! + idxn = max( 1, min(list%size+1, idxn ) ) + + ! + ! Check if the array list%string is large enough + ! Make room in any case + ! + if ( .not. allocated(list%string) ) then + allocate(list%string(1) ) + endif + + lastidx = list%size + number + + ! + ! Do we need a copy? + ! + if ( size(list%string) < lastidx ) then + allocate( new_string(lastidx) ) + + do i = 1,idxn-1 + call move_alloc( list%string(i)%value, new_string(i)%value ) + enddo + + do i = idxn, list%size + inew = i + number + call move_alloc( list%string(i)%value, new_string(inew)%value ) + enddo + call move_alloc( new_string, list%string ) + else + do i = idxn, list%size + inew = i + number + call move_alloc( list%string(i)%value, list%string(inew)%value ) + enddo + endif + + list%size = list%size + number + +end subroutine insert_empty_positions + +! insert_string_int_impl -- +! Insert a new string into the list - specific implementation +! +subroutine insert_string_int_impl( list, idx, string ) + class(stringlist_type), intent(inout) :: list + integer, intent(in) :: idx + character(len=*), intent(in) :: string + + integer :: idxn + type(string_type) :: new_element + type(string_type), dimension(:), allocatable :: new_string + + idxn = idx + call insert_empty_positions( list, idxn, 1 ) + + list%string(idxn)%value = string + +end subroutine insert_string_int_impl + +! insert_stringlist_int_impl -- +! Insert a list of strings into the list - specific implementation +! +subroutine insert_stringlist_int_impl( list, idx, slist ) + class(stringlist_type), intent(inout) :: list + integer, intent(in) :: idx + class(stringlist_type), intent(in) :: slist + + integer :: i + integer :: idxn, idxnew + + idxn = idx + call insert_empty_positions( list, idxn, slist%size ) + + do i = 1, slist%size + idxnew = max( 1, idxn ) + i - 1 + list%string(idxnew)%value = slist%string(i)%value + enddo + +end subroutine insert_stringlist_int_impl + +! insert_stringarray_int_impl -- +! Insert an array of strings into the list - specific implementatinon +! +subroutine insert_stringarray_int_impl( list, idx, sarray ) + class(stringlist_type), intent(inout) :: list + integer, intent(in) :: idx + character(len=*), dimension(:), intent(in) :: sarray + + integer :: i + integer :: idxn, idxnew + + idxn = idx + call insert_empty_positions( list, idxn, size(sarray) ) + + do i = 1, size(sarray) + idxnew = max( 1, idxn ) + i - 1 + list%string(idxnew)%value = sarray(i) + enddo + +end subroutine insert_stringarray_int_impl + +! get_string -- +! Get the string at a particular index +! +! Arguments: +! list The list of strings to retrieve the string from +! idx Index after which to insert the string +! +function get_string_idx_wrap( list, idx ) + class(stringlist_type), intent(in) :: list + type(stringlist_index_type), intent(in) :: idx + character(len=:), allocatable :: get_string_idx_wrap + + integer :: idxabs + + idxabs = merge( idx%offset, list%size + idx%offset, idx%head ) + + get_string_idx_wrap = list%get( idxabs ) +end function get_string_idx_wrap + +function get_string_int_impl( list, idx ) + class(stringlist_type), intent(in) :: list + integer, intent(in) :: idx + character(len=:), allocatable :: get_string_int_impl + + integer :: idxnew + + ! + ! Examine the actual index: + ! - if the index is larger than the size, return an empty string + ! - if the index is equal to list_head, interpret it as index 1 + ! - if the index is negative, calculate the absolute index + ! + if ( idx > list%size .or. idx < 1 ) then + get_string_int_impl = '' + else + get_string_int_impl = list%string(idx)%value + endif +end function get_string_int_impl + +! sort_list -- +! Sort the list and return the result as a new list +! +! Arguments: +! list The list of strings to retrieve the string from +! ascending Whether to sort as ascending (true) or not (false) +! +function sort_list( list, ascending ) + class(stringlist_type), intent(in) :: list + logical, intent(in), optional :: ascending + + integer :: i + integer, dimension(:), allocatable :: idx + class(stringlist_type), allocatable :: sort_list + logical :: ascending_order + + ! + ! Allocate and fill the index array, then sort the indices + ! based on the strings + ! + idx = [ (i ,i=1,list%size) ] + + ascending_order = .true. + if ( present(ascending) ) then + ascending_order = ascending + endif + + if ( ascending_order ) then + idx = sort_ascending( idx ) + else + idx = sort_descending( idx ) + endif + + allocate( sort_list ) + allocate( sort_list%string(list%size) ) + + do i = 1,list%size + sort_list%string(i) = list%string(idx(i)) + enddo + sort_list%size = list%size + +contains +recursive function sort_ascending( idx ) result(idxnew) + integer, dimension(:) :: idx + integer, dimension(size(idx)) :: idxnew + + if ( size(idx) > 1 ) then + idxnew = [ sort_ascending( pack( idx, list%string(idx) < list%string(idx(1)) ) ), & + pack( idx, list%string(idx) == list%string(idx(1)) ) , & + sort_ascending( pack( idx, list%string(idx) > list%string(idx(1)) ) ) ] + else + idxnew = idx + endif +end function sort_ascending + +recursive function sort_descending( idx ) result(idxnew) + integer, dimension(:) :: idx + integer, dimension(size(idx)) :: idxnew + + if ( size(idx) > 1 ) then + idxnew = [ sort_descending( pack( idx, list%string(idx) > list%string(idx(1)) ) ), & + pack( idx, list%string(idx) == list%string(idx(1)) ) , & + sort_descending( pack( idx, list%string(idx) < list%string(idx(1)) ) ) ] + else + idxnew = idx + endif +end function sort_descending + +end function sort_list + +! index_of_string -- +! Return the index in the list of a particular string +! +! Arguments: +! list The list of strings in which to search the string +! string The string to be found +! back Whether to search from the end (true) or not (false, default) +! +integer function index_of_string( list, string, back ) + class(stringlist_type), intent(in) :: list + character(len=*), intent(in) :: string + logical, intent(in), optional :: back + + integer :: idx + integer :: i + logical :: start_backwards + + start_backwards = .false. + if ( present(back) ) then + start_backwards = back + endif + + idx = 0 + if ( start_backwards) then + do i = list%size,1,-1 + if ( list%string(i)%value == string ) then + idx = i + exit + endif + enddo + else + do i = 1,list%size + if ( list%string(i)%value == string ) then + idx = i + exit + endif + enddo + endif + + index_of_string = idx +end function index_of_string + +! index_of_substring -- +! Return the index in the list of a string containing a particular substring +! +! Arguments: +! list The list of strings in which to search the string +! substring The substring to be found +! back Whether to search from the end (true) or not (false, default) +! +integer function index_of_substring( list, substring, back ) + class(stringlist_type), intent(in) :: list + character(len=*), intent(in) :: substring + logical, intent(in), optional :: back + + integer :: idx + integer :: i + logical :: start_backwards + + start_backwards = .false. + if ( present(back) ) then + start_backwards = back + endif + + idx = 0 + if ( start_backwards) then + do i = list%size,1,-1 + if ( index(list%string(i)%value, substring) > 0 ) then + idx = i + exit + endif + enddo + else + do i = 1,list%size + if ( index(list%string(i)%value, substring) > 0 ) then + idx = i + exit + endif + enddo + endif + + index_of_substring = idx +end function index_of_substring + +! delete_strings -- +! Delete one or more strings from the list +! +! Arguments: +! list The list of strings in which to search the string +! first The position of the first string to be deleted +! last The position of the last string to be deleted +! +! Note: +! If the range defined by first and last has a zero length or first > last, +! then nothing happens. +! +subroutine delete_strings_idx_idx_wrap( list, first, last ) + class(stringlist_type), intent(inout) :: list + type(stringlist_index_type), intent(in) :: first + type(stringlist_index_type), intent(in) :: last + + integer :: firstpos + integer :: lastpos + + firstpos = merge( first%offset, list%size + first%offset, first%head ) + lastpos = merge( last%offset, list%size + last%offset, last%head ) + + call list%delete( firstpos, lastpos ) +end subroutine delete_strings_idx_idx_wrap + +subroutine delete_strings_int_idx_wrap( list, first, last ) + class(stringlist_type), intent(inout) :: list + integer, intent(in) :: first + type(stringlist_index_type), intent(in) :: last + + integer :: firstpos + integer :: lastpos + + lastpos = merge( last%offset, list%size + last%offset, last%head ) + + call list%delete( firstpos, lastpos ) +end subroutine delete_strings_int_idx_wrap + +subroutine delete_strings_idx_int_wrap( list, first, last ) + class(stringlist_type), intent(inout) :: list + type(stringlist_index_type), intent(in) :: first + integer, intent(in) :: last + + integer :: firstpos + integer :: lastpos + + firstpos = merge( first%offset, list%size + first%offset, first%head ) + + call list%delete( firstpos, lastpos ) +end subroutine delete_strings_idx_int_wrap + +subroutine delete_strings_int_int_impl( list, first, last ) + class(stringlist_type), intent(inout) :: list + integer, intent(in) :: first + integer, intent(in) :: last + + integer :: firstpos + integer :: lastpos + integer :: i + integer :: j + + if ( first > list%size .or. last < 1 ) then + return + endif + + firstpos = max( 1, min(list%size, first ) ) + lastpos = max( 1, min(list%size, last ) ) + + if ( firstpos > lastpos ) then + return + else + do i = lastpos+1,list%size + j = firstpos + i - lastpos - 1 + call move_alloc( list%string(i)%value, list%string(j)%value ) + enddo + do i = list%size - (lastpos-firstpos), list%size + list%string(i)%value = '' + enddo + + list%size = list%size - (lastpos-firstpos + 1) + endif +end subroutine delete_strings_int_int_impl + +! range_list -- +! Return a sublist given by the first and last position +! +! Arguments: +! list The list of strings in which to search the string +! first The position of the first string to be deleted +! last The position of the last string to be deleted +! +! Note: +! If the range defined by first and last has a zero length or first > last, +! then return an empty list +! +function range_list_idx_idx_wrap( list, first, last ) + class(stringlist_type), intent(inout) :: list + type(stringlist_index_type), intent(in) :: first + type(stringlist_index_type), intent(in) :: last + class(stringlist_type), allocatable :: range_list_idx_idx_wrap + + integer :: firstpos + integer :: lastpos + + firstpos = merge( first%offset, list%size + first%offset, first%head ) + lastpos = merge( last%offset, list%size + last%offset, last%head ) + + range_list_idx_idx_wrap = list%range( firstpos, lastpos ) + +end function range_list_idx_idx_wrap + +function range_list_int_idx_wrap( list, first, last ) + class(stringlist_type), intent(inout) :: list + integer, intent(in) :: first + type(stringlist_index_type), intent(in) :: last + class(stringlist_type), allocatable :: range_list_int_idx_wrap + + integer :: lastpos + + lastpos = merge( last%offset, list%size + last%offset, last%head ) + + range_list_int_idx_wrap = list%range( first, lastpos ) + +end function range_list_int_idx_wrap + +function range_list_idx_int_wrap( list, first, last ) + class(stringlist_type), intent(inout) :: list + type(stringlist_index_type), intent(in) :: first + integer, intent(in) :: last + class(stringlist_type), allocatable :: range_list_idx_int_wrap + + integer :: firstpos + + firstpos = merge( first%offset, list%size + first%offset, first%head ) + + range_list_idx_int_wrap = list%range( firstpos, last ) + +end function range_list_idx_int_wrap + +function range_list_int_int_impl( list, first, last ) + class(stringlist_type), intent(inout) :: list + integer, intent(in) :: first + integer, intent(in) :: last + class(stringlist_type), allocatable :: range_list_int_int_impl + + integer :: firstpos + integer :: lastpos + + allocate( range_list_int_int_impl ) + + if ( first > list%size .or. last < 1 ) then + allocate( range_list_int_int_impl%string(0) ) + return + endif + + firstpos = max( 1, min(list%size, first ) ) + lastpos = max( 1, min(list%size, last ) ) + + if ( firstpos > lastpos ) then + allocate( range_list_int_int_impl%string(0) ) + return + else + range_list_int_int_impl%size = lastpos - firstpos + 1 + range_list_int_int_impl%string = list%string(firstpos:lastpos) + endif +end function range_list_int_int_impl + + +! replace_string -- +! Replace a string in the list +! +! Arguments: +! list The list of strings in which to replace a string (or a range of strings) +! first First index of the string(s) to be replaced +! last Last index of the string(s) to be replaced +! string The string in question (array of strings or another string list) +! +! Note: +! For convenience a version that simply replaces a single string is provided +! +subroutine replace_string_idx_wrap( list, idx, string ) + class(stringlist_type), intent(inout) :: list + type(stringlist_index_type), intent(in) :: idx + character(len=*), intent(in) :: string + + integer :: idxpos + + idxpos = merge( idx%offset, list%size + idx%offset, idx%head ) + + call list%replace( idxpos, string ) +end subroutine replace_string_idx_wrap + +subroutine replace_string_int_impl( list, idx, string ) + class(stringlist_type), intent(inout) :: list + integer, intent(in) :: idx + character(len=*), intent(in) :: string + + integer :: idxpos + + if ( idx < 1 .or. idx > list%size ) then + return + endif + + list%string(idx)%value = string +end subroutine replace_string_int_impl + +subroutine replace_string_idx_idx_wrap( list, first, last, string ) + class(stringlist_type), intent(inout) :: list + type(stringlist_index_type), intent(in) :: first + type(stringlist_index_type), intent(in) :: last + character(len=*), intent(in) :: string + + integer :: firstpos, lastpos + + firstpos = merge( first%offset, list%size + first%offset, first%head ) + lastpos = merge( last%offset, list%size + last%offset, last%head ) + + call list%replace( firstpos, lastpos, string ) +end subroutine replace_string_idx_idx_wrap + +subroutine replace_string_int_idx_wrap( list, first, last, string ) + class(stringlist_type), intent(inout) :: list + integer, intent(in) :: first + type(stringlist_index_type), intent(in) :: last + character(len=*), intent(in) :: string + + integer :: lastpos + + lastpos = merge( last%offset, list%size + last%offset, last%head ) + + call list%replace( first, lastpos, string ) +end subroutine replace_string_int_idx_wrap + +subroutine replace_string_idx_int_wrap( list, first, last, string ) + class(stringlist_type), intent(inout) :: list + type(stringlist_index_type), intent(in) :: first + integer, intent(in) :: last + character(len=*), intent(in) :: string + + integer :: firstpos + + firstpos = merge( first%offset, list%size + first%offset, first%head ) + + call list%replace( firstpos, last, string ) +end subroutine replace_string_idx_int_wrap + +subroutine replace_string_int_int_impl( list, first, last, string ) + class(stringlist_type), intent(inout) :: list + integer, intent(in) :: first + integer, intent(in) :: last + character(len=*), intent(in) :: string + + if ( first > list%size .or. last < 1 ) then + return + endif + if ( first > last ) then + return + endif + + call list%delete( first, last ) + call list%insert( first, string ) +end subroutine replace_string_int_int_impl + + +subroutine replace_stringlist_idx_idx_wrap( list, first, last, slist ) + class(stringlist_type), intent(inout) :: list + type(stringlist_index_type), intent(in) :: first + type(stringlist_index_type), intent(in) :: last + class(stringlist_type), intent(in) :: slist + + integer :: firstpos, lastpos + + firstpos = merge( first%offset, list%size + first%offset, first%head ) + lastpos = merge( last%offset, list%size + last%offset, last%head ) + + call list%replace( firstpos, lastpos, slist ) +end subroutine replace_stringlist_idx_idx_wrap + +subroutine replace_stringlist_int_idx_wrap( list, first, last, slist ) + class(stringlist_type), intent(inout) :: list + integer, intent(in) :: first + type(stringlist_index_type), intent(in) :: last + class(stringlist_type), intent(in) :: slist + + integer :: lastpos + + lastpos = merge( last%offset, list%size + last%offset, last%head ) + + call list%replace( first, lastpos, slist ) +end subroutine replace_stringlist_int_idx_wrap + +subroutine replace_stringlist_idx_int_wrap( list, first, last, slist ) + class(stringlist_type), intent(inout) :: list + type(stringlist_index_type), intent(in) :: first + integer, intent(in) :: last + class(stringlist_type), intent(in) :: slist + + integer :: firstpos + + firstpos = merge( first%offset, list%size + first%offset, first%head ) + + call list%replace( firstpos, last, slist ) +end subroutine replace_stringlist_idx_int_wrap + +subroutine replace_stringlist_int_int_impl( list, first, last, slist ) + class(stringlist_type), intent(inout) :: list + integer, intent(in) :: first + integer, intent(in) :: last + class(stringlist_type), intent(in) :: slist + + if ( first > list%size .or. last < 1 ) then + return + endif + if ( first > last ) then + return + endif + + call list%delete( first, last ) + call list%insert( first, slist ) +end subroutine replace_stringlist_int_int_impl + + +subroutine replace_stringarray_idx_idx_wrap( list, first, last, sarray ) + class(stringlist_type), intent(inout) :: list + type(stringlist_index_type), intent(in) :: first + type(stringlist_index_type), intent(in) :: last + character(len=*), dimension(:), intent(in) :: sarray + + integer :: firstpos, lastpos + + firstpos = merge( first%offset, list%size + first%offset, first%head ) + lastpos = merge( last%offset, list%size + last%offset, last%head ) + + call list%replace( firstpos, lastpos, sarray ) +end subroutine replace_stringarray_idx_idx_wrap + +subroutine replace_stringarray_int_idx_wrap( list, first, last, sarray ) + class(stringlist_type), intent(inout) :: list + integer, intent(in) :: first + type(stringlist_index_type), intent(in) :: last + character(len=*), dimension(:), intent(in) :: sarray + + integer :: lastpos + + lastpos = merge( last%offset, list%size + last%offset, last%head ) + + call list%replace( first, lastpos, sarray ) +end subroutine replace_stringarray_int_idx_wrap + +subroutine replace_stringarray_idx_int_wrap( list, first, last, sarray ) + class(stringlist_type), intent(inout) :: list + type(stringlist_index_type), intent(in) :: first + integer, intent(in) :: last + character(len=*), dimension(:), intent(in) :: sarray + + integer :: firstpos + + firstpos = merge( first%offset, list%size + first%offset, first%head ) + + call list%replace( firstpos, last, sarray ) +end subroutine replace_stringarray_idx_int_wrap + +subroutine replace_stringarray_int_int_impl( list, first, last, sarray ) + class(stringlist_type), intent(inout) :: list + integer, intent(in) :: first + integer, intent(in) :: last + character(len=*), dimension(:), intent(in) :: sarray + + if ( first > list%size .or. last < 1 ) then + return + endif + if ( first > last ) then + return + endif + + call list%delete( first, last ) + call list%insert( first, sarray ) +end subroutine replace_stringarray_int_int_impl + +end module stdlib_stringlist diff --git a/src/tests/stringlist/CMakeLists.txt b/src/tests/stringlist/CMakeLists.txt new file mode 100644 index 000000000..7bf83a41a --- /dev/null +++ b/src/tests/stringlist/CMakeLists.txt @@ -0,0 +1,4 @@ +ADDTEST(insert) +ADDTEST(delete) +ADDTEST(find) +ADDTEST(replace_append) diff --git a/src/tests/stringlist/test_delete.f90 b/src/tests/stringlist/test_delete.f90 new file mode 100644 index 000000000..5c3cf0870 --- /dev/null +++ b/src/tests/stringlist/test_delete.f90 @@ -0,0 +1,57 @@ +! test_delete.f90 -- +! Test the delete routine +! +program test_deletion + use stdlib_stringlist + + type(stringlist_type) :: list + + + call list%insert( 1, ["A", "B", "C", "D", "E", "F"] ) + + call list%delete( 1, 1 ) + + write(*,*) 'Expected: B, C, D, E, F (5)' + call print_list( list ) + + call list%delete( list_end, list_end ) + + write(*,*) 'Expected: B, C, D, E (4)' + call print_list( list ) + + call list%delete( list_end+1, list_end+1 ) + + write(*,*) 'Expected: B, C, D, E (4)' + call print_list( list ) + + call list%delete( 3, 2 ) + + write(*,*) 'Expected: B, C, D, E (4)' + call print_list( list ) + + call list%delete( 2, 3 ) + + write(*,*) 'Expected: B, E (2)' + call print_list( list ) + +contains +subroutine renew_list( list ) + type(stringlist_type), intent(inout) :: list + + call list%destroy + call list%insert( 1, "A" ) + call list%insert( 2, "B" ) + call list%insert( 3, "C" ) +end subroutine renew_list + +subroutine print_list( list ) + type(stringlist_type), intent(in) :: list + + write(*,*) list%length() + + do i = 1,list%length() + write(*,*) '>', list%get(i), '<' + enddo +end subroutine print_list + +end program test_deletion diff --git a/src/tests/stringlist/test_find.f90 b/src/tests/stringlist/test_find.f90 new file mode 100644 index 000000000..3db7bd806 --- /dev/null +++ b/src/tests/stringlist/test_find.f90 @@ -0,0 +1,72 @@ +! test_find.f90 -- +! Test the various retrieval routines +! +program test_find + use stdlib_stringlist + + type(stringlist_type) :: list, sublist + character(len=:), allocatable :: string + + call list%insert( 1, ["A", "B", "C", "D", "E", "F"] ) + + write(*,*) 'Expected: A' + write(*,*) list%get(1) + write(*,*) list%get(list_head) + write(*,*) 'Expected: B' + write(*,*) list%get(list_head+1) + write(*,*) 'Expected: F' + write(*,*) list%get(list_end) + write(*,*) 'Expected: (nothing)' + write(*,*) list%get(list_end+1) + + call list%destroy + call list%insert( 1, ["AA", "BA", "CA", "AA", "BA", "CA"] ) + write(*,*) 'Expected: 1' + write(*,*) list%index("AA") + write(*,*) 'Expected: 4' + write(*,*) list%index("AA", .true.) + write(*,*) 'Expected: 0' + write(*,*) list%index("XXXX") + + write(*,*) 'Expected: 2' + write(*,*) list%index_sub("B") + write(*,*) 'Expected: 5' + write(*,*) list%index_sub("B", .true.) + write(*,*) 'Expected: 0' + write(*,*) list%index_sub("X") + + write(*,*) 'Expected: 6', list%length() + + sublist = list%range(1, 2) + write(*,*) 'Expected: AA, BA' + call print_list( sublist ) + + sublist = list%range(list_end-1, list_end+2) + write(*,*) 'Expected: BA, CA' + call print_list( sublist ) + + sublist = list%range(-1, 3) + write(*,*) 'Expected: AA, BA, CA' + call print_list( sublist ) + +contains +subroutine renew_list( list ) + type(stringlist_type), intent(inout) :: list + + call list%destroy + call list%insert( 1, "A" ) + call list%insert( 2, "B" ) + call list%insert( 3, "C" ) +end subroutine renew_list + +subroutine print_list( list ) + type(stringlist_type), intent(in) :: list + + write(*,*) list%length() + + do i = 1,list%length() + write(*,*) '>', list%get(i), '<' + enddo +end subroutine print_list + +end program test_find diff --git a/src/tests/stringlist/test_insert.f90 b/src/tests/stringlist/test_insert.f90 new file mode 100644 index 000000000..6aa6b1198 --- /dev/null +++ b/src/tests/stringlist/test_insert.f90 @@ -0,0 +1,91 @@ +! test_insert.f90 -- +! Test the insertion routine +! +program test_insertion + use stdlib_stringlist + + type(stringlist_type) :: list, second_list + character(len=10), dimension(3) :: sarray + + + call list%insert( 1, "C" ) + call list%insert( 1, "B" ) + call list%insert( 1, "A" ) + + write(*,*) 'Expected: A, B, C (3)' + call print_list( list ) + + call list%insert( 6, "D" ) + + write(*,*) 'Expected: A, B, C, D (4)' + call print_list( list ) + + call list%insert( -1, "X" ) + + write(*,*) 'Expected: X, A, B, C, D (5)' + call print_list( list ) + + call list%insert( list_end-1, "Y" ) + + write(*,*) 'Expected: X, A, B, Y, C, D (6)' + call print_list( list ) + + call list%insert( list_end+1, "Z" ) + + write(*,*) 'Expected: X, A, B, Y, C, D, Z (7)' + call print_list( list ) + + ! + ! Try inserting a second list + ! + call renew_list( list ) + + call second_list%insert( 1, "SecondA" ) + call second_list%insert( 2, "SecondB" ) + + call list%insert( 2, second_list ) + call print_list( list ) + + call renew_list( list ) + + call list%insert( list_after_end, second_list ) + call print_list( list ) + + ! + ! Try inserting an array + ! + call renew_list( list ) + + sarray(1) = "ThirdA" + sarray(2) = "ThirdB" + sarray(3) = "ThirdC" + + call list%insert( list_head, sarray ) + call print_list( list ) + + call renew_list( list ) + + call list%insert( 2, sarray ) + call print_list( list ) + +contains +subroutine renew_list( list ) + type(stringlist_type), intent(inout) :: list + + call list%destroy + call list%insert( 1, "A" ) + call list%insert( 2, "B" ) + call list%insert( 3, "C" ) +end subroutine renew_list + +subroutine print_list( list ) + type(stringlist_type), intent(in) :: list + + write(*,*) list%length() + + do i = 1,list%length() + write(*,*) '>', list%get(i), '<' + enddo +end subroutine print_list + +end program test_insertion diff --git a/src/tests/stringlist/test_replace_append.f90 b/src/tests/stringlist/test_replace_append.f90 new file mode 100644 index 000000000..b7c0c26ed --- /dev/null +++ b/src/tests/stringlist/test_replace_append.f90 @@ -0,0 +1,88 @@ +! test_replace_append.f90 -- +! Test the replace and append routines +! +program test_replace_append + use stdlib_stringlist + + type(stringlist_type) :: list, newlist + + call list%insert( 1, ["A", "B", "C", "D", "E", "F"] ) + + newlist = 'Long string' // list + + write(*,*) 'Expected: "Long string, A, B, C, D, E, F (7)' + call print_list( newlist ) + + newlist = list // 'Long string' + + write(*,*) 'Expected: A, B, C, D, E, F, "Long string" (7)' + call print_list( newlist ) + + newlist = list // list + + write(*,*) 'Expected: A, B, C, D, E, F (twice, 12 elements)' + call print_list( newlist ) + + newlist = ['AA', 'BB'] // list + write(*,*) 'Expected: AA, BB, A, B, C, D, E, F (8)' + call print_list( newlist ) + + newlist = list // ['AA', 'BB'] + write(*,*) 'Expected: A, B, C, D, E, F, AA, BB (8)' + call print_list( newlist ) + + ! + ! Replace ... quite a variety + ! + newlist = list + call newlist%replace( 1, "New string" ) + write(*,*) 'Expected: "New string", B, C, D, E, F (6)' + call print_list( newlist ) + + newlist = list + call newlist%replace( list_head, "New string" ) + write(*,*) 'Expected: "New string", B, C, D, E, F (6)' + call print_list( newlist ) + + newlist = list + call newlist%replace( list_end, "New string" ) + write(*,*) 'Expected: A, B, C, D, E, F, "New string" (6)' + call print_list( newlist ) + + newlist = list + call newlist%replace( 5, list_end, "X" ) + write(*,*) 'Expected: A, B, C, D, X (5)' + call print_list( newlist ) + + newlist = list + call newlist%replace( 5, list_end-2, "X" ) + write(*,*) 'Expected: A, B, C, D, E, F (6 - no change)' + call print_list( newlist ) + + newlist = list + call newlist%replace( 1, 2, ["WW", "XX", "YY", "ZZ"] ) + write(*,*) 'Expected: WW, XX, YY, ZZ, C, D, E, F (8)' + call print_list( newlist ) + + newlist = list + call newlist%replace( list_end-1, list_end, ["WW", "XX", "YY", "ZZ"] ) + write(*,*) 'Expected: A, B, C, D, WW, XX, YY, ZZ (8)' + call print_list( newlist ) + + newlist = list + call newlist%replace( list_end-1, list_end, list ) + write(*,*) 'Expected: A, B, C, D, A, B, C, D, E, F (10)' + call print_list( newlist ) + +contains +subroutine print_list( list ) + type(stringlist_type), intent(in) :: list + + write(*,*) list%length() + + do i = 1,list%length() + write(*,*) '>', list%get(i), '<' + enddo +end subroutine print_list + +end program test_replace_append From 320caed455e7cef46d67cb2c7378579c4113cdda Mon Sep 17 00:00:00 2001 From: arjenmarkus Date: Thu, 4 Feb 2021 10:38:57 +0100 Subject: [PATCH 02/40] Correct typo There was a typo in some comments - corrected --- src/stdlib_stringlist.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stdlib_stringlist.f90 b/src/stdlib_stringlist.f90 index 4dfb192ed..570927d7b 100644 --- a/src/stdlib_stringlist.f90 +++ b/src/stdlib_stringlist.f90 @@ -145,12 +145,12 @@ function stringlist_index_add( index, offset ) stringlist_index_add%offset = stringlist_index_add%offset + offset end function stringlist_index_add -! stringlist_index_substract -- +! stringlist_index_subtract -- ! Subtract an integer offset to the special index ! ! Arguments: ! index Special index -! offset Offset to be substracted +! offset Offset to be subtracted ! function stringlist_index_subtract( index, offset ) type(stringlist_index_type), intent(in) :: index From c75dd20e2ecaeba7ce8847d08334a931ef634f3e Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Sat, 24 Jul 2021 12:26:19 +0530 Subject: [PATCH 03/40] fixed a bug in append_stringlist --- src/stdlib_stringlist.f90 | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/stdlib_stringlist.f90 b/src/stdlib_stringlist.f90 index 570927d7b..d7dcfb737 100644 --- a/src/stdlib_stringlist.f90 +++ b/src/stdlib_stringlist.f90 @@ -204,13 +204,14 @@ function prepend_string( string, list ) call prepend_string%insert( list_head, string ) end function prepend_string -function append_stringlist( slist, list ) - type(stringlist_type), intent(in) :: list - type(stringlist_type), intent(in) :: slist - type(stringlist_type) :: append_stringlist +function append_stringlist( list, slist ) + type(stringlist_type), intent(in) :: list + type(stringlist_type), intent(in) :: slist + type(stringlist_type) :: append_stringlist + + append_stringlist = list + call append_stringlist%insert( list_after_end, slist ) - append_stringlist = list - call append_stringlist%insert( list_after_end, slist ) end function append_stringlist function append_stringarray( list, sarray ) From ecaa0bf74dc6ab48a6fb301a1f8ec14cef19ad90 Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Sat, 24 Jul 2021 12:29:35 +0530 Subject: [PATCH 04/40] used concept of forward backward indexes, refactored code to use stdlib's string_type, provided suppport for allocatable character --- src/stdlib_stringlist.f90 | 1466 +++++++++++++++++++------------------ 1 file changed, 770 insertions(+), 696 deletions(-) diff --git a/src/stdlib_stringlist.f90 b/src/stdlib_stringlist.f90 index d7dcfb737..80e104ed1 100644 --- a/src/stdlib_stringlist.f90 +++ b/src/stdlib_stringlist.f90 @@ -1,5 +1,5 @@ ! stdlib_stringlist.f90 -- -! Module for storing and manipulating lists of strings +! Module for storing and manipulating list of strings ! The strings may have arbitrary lengths, not necessarily the same ! ! Note: very preliminary @@ -16,41 +16,48 @@ ! Limited to implemented routines ! module stdlib_stringlist + use stdlib_string_type, only: string_type, move, assignment(=) !, char, operator(==) + use stdlib_math, only: clip + use stdlib_optval, only: optval implicit none - private - public :: stringlist_type - public :: operator(//) - public :: operator(+) - public :: operator(-) - public :: list_end + + public :: stringlist_type, operator(//) + public :: list_head, list_tail, fidx, bidx !, operator(+), operator(-) type stringlist_index_type private logical :: head integer :: offset + end type stringlist_index_type - type(stringlist_index_type), parameter :: list_head = stringlist_index_type( .true., 1 ) - type(stringlist_index_type), parameter :: list_end = stringlist_index_type( .false., 0 ) - type(stringlist_index_type), parameter :: list_after_end = stringlist_index_type( .false., 1 ) + type(stringlist_index_type), parameter :: list_head = forward_index(1) + ! type(stringlist_index_type), parameter :: list_end = stringlist_index_type( .false., 0 ) + ! type(stringlist_index_type), parameter :: list_after_end = stringlist_index_type( .false., 1 ) + type(stringlist_index_type), parameter :: list_tail = backward_index(1) - interface operator(+) - module procedure stringlist_index_add - end interface + ! interface operator(+) + ! module procedure stringlist_index_add + ! end interface + + ! interface operator(-) + ! module procedure stringlist_index_subtract + ! end interface - interface operator(-) - module procedure stringlist_index_subtract + interface fidx + module procedure forward_index end interface - type string_type - character(len=:), allocatable :: value - end type string_type + interface bidx + module procedure backward_index + end interface type stringlist_type private integer :: size = 0 - type(string_type), dimension(:), allocatable :: string + type(string_type), dimension(:), allocatable :: stringarray + contains private procedure, public :: destroy => destroy_list @@ -66,68 +73,61 @@ module stdlib_stringlist procedure :: get_string_int => get_string_int_impl procedure :: get_string_idx => get_string_idx_wrap generic, public :: get => get_string_int, get_string_idx - procedure, public :: length => length_list - procedure, public :: sort => sort_list - procedure, public :: index => index_of_string - procedure, public :: index_sub => index_of_substring - procedure :: delete_strings_int_int => delete_strings_int_int_impl - procedure :: delete_strings_idx_int => delete_strings_idx_int_wrap - procedure :: delete_strings_int_idx => delete_strings_int_idx_wrap - procedure :: delete_strings_idx_idx => delete_strings_idx_idx_wrap - generic, public :: delete => delete_strings_int_int, delete_strings_idx_int, & - delete_strings_int_idx, delete_strings_idx_idx - procedure :: range_list_int_int => range_list_int_int_impl - procedure :: range_list_idx_int => range_list_idx_int_wrap - procedure :: range_list_int_idx => range_list_int_idx_wrap - procedure :: range_list_idx_idx => range_list_idx_idx_wrap - generic, public :: range => range_list_int_int, range_list_idx_idx, & - range_list_int_idx, range_list_idx_int - procedure :: replace_string_idx => replace_string_idx_wrap - procedure :: replace_string_int => replace_string_int_impl - procedure :: replace_string_int_int => replace_string_int_int_impl - procedure :: replace_stringarray_int_int => replace_stringarray_int_int_impl - procedure :: replace_stringlist_int_int => replace_stringlist_int_int_impl - procedure :: replace_string_idx_idx => replace_string_idx_idx_wrap - procedure :: replace_stringarray_idx_idx => replace_stringarray_idx_idx_wrap - procedure :: replace_stringlist_idx_idx => replace_stringlist_idx_idx_wrap - procedure :: replace_string_idx_int => replace_string_idx_int_wrap - procedure :: replace_stringarray_idx_int => replace_stringarray_idx_int_wrap - procedure :: replace_stringlist_idx_int => replace_stringlist_idx_int_wrap - procedure :: replace_string_int_idx => replace_string_int_idx_wrap - procedure :: replace_stringarray_int_idx => replace_stringarray_int_idx_wrap - procedure :: replace_stringlist_int_idx => replace_stringlist_int_idx_wrap - generic, public :: replace => replace_string_int_int, replace_stringarray_int_int, & - replace_stringlist_int_int, & - replace_string_idx, replace_string_int, & - replace_string_idx_idx, replace_stringarray_idx_idx, & - replace_stringlist_idx_idx, & - replace_string_idx_int, replace_stringarray_idx_int, & - replace_stringlist_idx_int, & - replace_string_int_idx, replace_stringarray_int_idx, & - replace_stringlist_int_idx - end type stringlist_type - - interface operator(<) - module procedure string_lower - end interface - - interface operator(>) - module procedure string_greater - end interface + procedure, public :: len => length_list + ! procedure, public :: sort => sort_list + ! procedure, public :: index => index_of_string, index_of_char + ! procedure, public :: index_sub => index_of_substring, index_of_subchar + ! procedure :: delete_strings_int_int => delete_strings_int_int_impl + ! procedure :: delete_strings_idx_int => delete_strings_idx_int_wrap + ! procedure :: delete_strings_int_idx => delete_strings_int_idx_wrap + ! procedure :: delete_strings_idx_idx => delete_strings_idx_idx_wrap + ! generic, public :: delete => delete_strings_int_int, delete_strings_idx_int, & + ! delete_strings_int_idx, delete_strings_idx_idx + ! procedure :: range_list_int_int => range_list_int_int_impl + ! procedure :: range_list_idx_int => range_list_idx_int_wrap + ! procedure :: range_list_int_idx => range_list_int_idx_wrap + ! procedure :: range_list_idx_idx => range_list_idx_idx_wrap + ! generic, public :: range => range_list_int_int, range_list_idx_idx, & + ! range_list_int_idx, range_list_idx_int + ! procedure :: replace_string_idx => replace_string_idx_wrap + ! procedure :: replace_string_int => replace_string_int_impl + ! procedure :: replace_string_int_int => replace_string_int_int_impl + ! procedure :: replace_stringarray_int_int => replace_stringarray_int_int_impl + ! procedure :: replace_stringlist_int_int => replace_stringlist_int_int_impl + ! procedure :: replace_string_idx_idx => replace_string_idx_idx_wrap + ! procedure :: replace_stringarray_idx_idx => replace_stringarray_idx_idx_wrap + ! procedure :: replace_stringlist_idx_idx => replace_stringlist_idx_idx_wrap + ! procedure :: replace_string_idx_int => replace_string_idx_int_wrap + ! procedure :: replace_stringarray_idx_int => replace_stringarray_idx_int_wrap + ! procedure :: replace_stringlist_idx_int => replace_stringlist_idx_int_wrap + ! procedure :: replace_string_int_idx => replace_string_int_idx_wrap + ! procedure :: replace_stringarray_int_idx => replace_stringarray_int_idx_wrap + ! procedure :: replace_stringlist_int_idx => replace_stringlist_int_idx_wrap + ! generic, public :: replace => replace_string_int_int, replace_stringarray_int_int, & + ! replace_stringlist_int_int, & + ! replace_string_idx, replace_string_int, & + ! replace_string_idx_idx, replace_stringarray_idx_idx, & + ! replace_stringlist_idx_idx, & + ! replace_string_idx_int, replace_stringarray_idx_int, & + ! replace_stringlist_idx_int, & + ! replace_string_int_idx, replace_stringarray_int_idx, & + ! replace_stringlist_int_idx - interface operator(==) - module procedure string_equal - end interface + end type stringlist_type interface operator(//) + module procedure append_char module procedure append_string + module procedure prepend_char module procedure prepend_string module procedure append_stringlist module procedure append_stringarray module procedure prepend_stringarray end interface + contains + ! stringlist_index_add -- ! Add an integer offset to the special index ! @@ -135,15 +135,16 @@ module stdlib_stringlist ! index Special index ! offset Offset to be added ! -function stringlist_index_add( index, offset ) - type(stringlist_index_type), intent(in) :: index - integer, intent(in) :: offset +! function stringlist_index_add( index, offset ) +! type(stringlist_index_type), intent(in) :: index +! integer, intent(in) :: offset + +! type(stringlist_index_type) :: stringlist_index_add - type(stringlist_index_type) :: stringlist_index_add +! stringlist_index_add = index +! stringlist_index_add%offset = stringlist_index_add%offset + offset - stringlist_index_add = index - stringlist_index_add%offset = stringlist_index_add%offset + offset -end function stringlist_index_add +! end function stringlist_index_add ! stringlist_index_subtract -- ! Subtract an integer offset to the special index @@ -152,98 +153,122 @@ end function stringlist_index_add ! index Special index ! offset Offset to be subtracted ! -function stringlist_index_subtract( index, offset ) - type(stringlist_index_type), intent(in) :: index - integer, intent(in) :: offset +! function stringlist_index_subtract( index, offset ) +! type(stringlist_index_type), intent(in) :: index +! integer, intent(in) :: offset - type(stringlist_index_type) :: stringlist_index_subtract +! type(stringlist_index_type) :: stringlist_index_subtract - stringlist_index_subtract = index - stringlist_index_subtract%offset = stringlist_index_subtract%offset - offset -end function stringlist_index_subtract +! stringlist_index_subtract = index +! stringlist_index_subtract%offset = stringlist_index_subtract%offset - offset -! compare string_type derived types -! Required by sorting functions -! -elemental logical function string_lower( string1, string2 ) - type(string_type), intent(in) :: string1 - type(string_type), intent(in) :: string2 +! end function stringlist_index_subtract - string_lower = string1%value < string2%value -end function string_lower +pure function forward_index(idx) + integer, intent(in) :: idx + type(stringlist_index_type) :: forward_index -elemental logical function string_greater( string1, string2 ) - type(string_type), intent(in) :: string1 - type(string_type), intent(in) :: string2 + forward_index = stringlist_index_type( .true., idx ) - string_greater = string1%value > string2%value -end function string_greater +end function forward_index -elemental logical function string_equal( string1, string2 ) - type(string_type), intent(in) :: string1 - type(string_type), intent(in) :: string2 +pure function backward_index(idx) + integer, intent(in) :: idx + type(stringlist_index_type) :: backward_index - string_equal = string1%value == string2%value -end function string_equal + backward_index = stringlist_index_type( .false., idx ) -function append_string( list, string ) - type(stringlist_type), intent(in) :: list - character(len=*), intent(in) :: string - type(stringlist_type) :: append_string +end function backward_index + +pure function append_char( list, string ) + type(stringlist_type), intent(in) :: list + character(len=*), intent(in) :: string + type(stringlist_type) :: append_char + + append_char = list // string_type( string ) + +end function append_char + +pure function append_string( list, string ) + type(stringlist_type), intent(in) :: list + type(string_type), intent(in) :: string + type(stringlist_type) :: append_string + + append_string = list + call append_string%insert( list_tail, string ) - append_string = list - call append_string%insert( list_after_end, string ) end function append_string -function prepend_string( string, list ) - character(len=*), intent(in) :: string - type(stringlist_type), intent(in) :: list - type(stringlist_type) :: prepend_string +pure function prepend_char( string, list ) + character(len=*), intent(in) :: string + type(stringlist_type), intent(in) :: list + type(stringlist_type) :: prepend_char + + prepend_char = string_type( string ) // list + +end function prepend_char + +pure function prepend_string( string, list ) + type(string_type), intent(in) :: string + type(stringlist_type), intent(in) :: list + type(stringlist_type) :: prepend_string + + prepend_string = list + call prepend_string%insert( list_head, string ) - prepend_string = list - call prepend_string%insert( list_head, string ) end function prepend_string +<<<<<<< Updated upstream function append_stringlist( list, slist ) +======= +pure function append_stringlist( list, slist ) +>>>>>>> Stashed changes type(stringlist_type), intent(in) :: list type(stringlist_type), intent(in) :: slist type(stringlist_type) :: append_stringlist append_stringlist = list +<<<<<<< Updated upstream call append_stringlist%insert( list_after_end, slist ) +======= + call append_stringlist%insert( list_tail, slist ) +>>>>>>> Stashed changes end function append_stringlist -function append_stringarray( list, sarray ) - type(stringlist_type), intent(in) :: list - character(len=*), dimension(:), intent(in) :: sarray - type(stringlist_type) :: append_stringarray +pure function append_stringarray( list, sarray ) + type(stringlist_type), intent(in) :: list + character(len=*), dimension(:), intent(in) :: sarray + type(stringlist_type) :: append_stringarray + + append_stringarray = list + call append_stringarray%insert( list_tail, sarray ) - append_stringarray = list - call append_stringarray%insert( list_after_end, sarray ) end function append_stringarray -function prepend_stringarray( sarray, list ) - character(len=*), dimension(:), intent(in) :: sarray - type(stringlist_type), intent(in) :: list - type(stringlist_type) :: prepend_stringarray +pure function prepend_stringarray( sarray, list ) + character(len=*), dimension(:), intent(in) :: sarray + type(stringlist_type), intent(in) :: list + type(stringlist_type) :: prepend_stringarray + + prepend_stringarray = list + call prepend_stringarray%insert( list_head, sarray ) - prepend_stringarray = list - call prepend_stringarray%insert( list_head, sarray ) end function prepend_stringarray ! destroy_list -- -! Destroy the contetns of the list +! Destroy the contents of the list ! ! Arguments: ! list The list of strings in question ! subroutine destroy_list( list ) - class(stringlist_type), intent(inout) :: list + type(stringlist_type), intent(out) :: list list%size = 0 - deallocate( list%string ) + deallocate( list%stringarray ) + end subroutine destroy_list ! length_list -- @@ -252,12 +277,32 @@ end subroutine destroy_list ! Arguments: ! list The list of strings to retrieve the string from ! -integer function length_list( list ) - class(stringlist_type), intent(in) :: list +pure integer function length_list( list ) + type(stringlist_type), intent(in) :: list length_list = list%size + end function length_list +pure integer function capacity( list ) + type(stringlist_type), intent(in) :: list + + capacity = 0 + if ( allocated(list%stringarray) ) then + capacity = size(list%stringarray) + end if + +end function capacity + +! Convert fidx and bidx to the equivalent integer +pure integer function to_idxn( idx ) + type(stringlist_index_type), intent(in) :: idx + integer :: to_idxn + + to_idxn = merge( idx%offset, list%size + 2 - idx%offset, idx%head ) + +end function to_idxn + ! insert_string -- ! Insert a new string (or an array of strings of another list) into the list ! @@ -266,40 +311,40 @@ end function length_list ! idx Index at which to insert the string ! string The string in question ! -subroutine insert_string_idx_wrap( list, idx, string ) - class(stringlist_type), intent(inout) :: list - type(stringlist_index_type), intent(in) :: idx - character(len=*), intent(in) :: string +subroutine insert_char_idx_wrap( list, idx, string ) + type(stringlist_type), intent(inout) :: list + type(stringlist_index_type), intent(in) :: idx + character(len=*), intent(in) :: string - integer :: idxabs + call list%insert( idx, string_type( string ) ) - idxabs = merge( idx%offset, list%size + idx%offset, idx%head ) +end subroutine insert_char_idx_wrap + +subroutine insert_string_idx_wrap( list, idx, string ) + type(stringlist_type), intent(inout) :: list + type(stringlist_index_type), intent(in) :: idx + type(type_string), intent(in) :: string + + call list%insert( to_idxn(idx), string ) - call list%insert( idxabs, string ) end subroutine insert_string_idx_wrap subroutine insert_stringlist_idx_wrap( list, idx, slist ) - class(stringlist_type), intent(inout) :: list - type(stringlist_index_type), intent(in) :: idx - class(stringlist_type), intent(in) :: slist - - integer :: idxabs + type(stringlist_type), intent(inout) :: list + type(stringlist_index_type), intent(in) :: idx + type(stringlist_type), intent(in) :: slist - idxabs = merge( idx%offset, list%size + idx%offset, idx%head ) + call list%insert( to_idxn(idx), slist ) - call list%insert( idxabs, slist ) end subroutine insert_stringlist_idx_wrap subroutine insert_stringarray_idx_wrap( list, idx, sarray ) - class(stringlist_type), intent(inout) :: list - type(stringlist_index_type), intent(in) :: idx - character(len=*), dimension(:), intent(in) :: sarray - - integer :: idxabs + type(stringlist_type), intent(inout) :: list + type(stringlist_index_type), intent(in) :: idx + character(len=*), dimension(:), intent(in) :: sarray - idxabs = merge( idx%offset, list%size + idx%offset, idx%head ) + call list%insert( to_idxn(idx), sarray ) - call list%insert( idxabs, sarray ) end subroutine insert_stringarray_idx_wrap ! insert_empty_positions @@ -311,71 +356,75 @@ end subroutine insert_stringarray_idx_wrap ! number Number of positions ! subroutine insert_empty_positions( list, idxn, number ) - class(stringlist_type), intent(inout) :: list + type(stringlist_type), intent(inout) :: list integer, intent(inout) :: idxn - integer, intent(in) :: number + integer, intent(inout) :: number integer :: i, inew - integer :: lastidx - type(string_type), dimension(:), allocatable :: new_string + integer :: new_size, old_size + type(string_type), dimension(:), allocatable :: new_stringarray - ! - ! Clip the index between 1 and size+1 - ! - idxn = max( 1, min(list%size+1, idxn ) ) + if (number > 0) then - ! - ! Check if the array list%string is large enough - ! Make room in any case - ! - if ( .not. allocated(list%string) ) then - allocate(list%string(1) ) - endif + idxn = clip( idxn, 1, len(list) + 1 ) + old_size = len(list) + new_size = old_size + number - lastidx = list%size + number + if ( capacity(list) < new_size ) then - ! - ! Do we need a copy? - ! - if ( size(list%string) < lastidx ) then - allocate( new_string(lastidx) ) - - do i = 1,idxn-1 - call move_alloc( list%string(i)%value, new_string(i)%value ) - enddo - - do i = idxn, list%size - inew = i + number - call move_alloc( list%string(i)%value, new_string(inew)%value ) - enddo - call move_alloc( new_string, list%string ) - else - do i = idxn, list%size - inew = i + number - call move_alloc( list%string(i)%value, list%string(inew)%value ) - enddo - endif + allocate( new_stringarray(new_size) ) + + do i = 1, idxn - 1 + call move( list%stringarray(i), new_stringarray(i) ) + end do + do i = idxn, old_size + inew = i + number + call move( list%stringarray(i), new_stringarray(inew) ) + end do + + call move_alloc( new_stringarray, list%stringarray ) + + else + do i = old_size, idxn, -1 + inew = i + number + call move( list%stringarray(i), list%stringarray(inew) ) + end do + end if - list%size = list%size + number + list%size = new_size + + else + number = 0 + end if end subroutine insert_empty_positions +! insert_char_int_impl -- +! Insert a new string into the list - specific implementation +! +subroutine insert_char_int_impl( list, idx, string ) + type(stringlist_type), intent(inout) :: list + integer, intent(in) :: idx + character(len=*), intent(in) :: string + + call insert( list, idx, string_type(string) ) + +end subroutine insert_char_int_impl + ! insert_string_int_impl -- ! Insert a new string into the list - specific implementation ! subroutine insert_string_int_impl( list, idx, string ) - class(stringlist_type), intent(inout) :: list + type(stringlist_type), intent(inout) :: list integer, intent(in) :: idx - character(len=*), intent(in) :: string + type(string_type), intent(in) :: string integer :: idxn - type(string_type) :: new_element - type(string_type), dimension(:), allocatable :: new_string idxn = idx call insert_empty_positions( list, idxn, 1 ) - list%string(idxn)%value = string + list%stringarray(idxn) = string end subroutine insert_string_int_impl @@ -383,30 +432,51 @@ end subroutine insert_string_int_impl ! Insert a list of strings into the list - specific implementation ! subroutine insert_stringlist_int_impl( list, idx, slist ) - class(stringlist_type), intent(inout) :: list + type(stringlist_type), intent(inout) :: list integer, intent(in) :: idx - class(stringlist_type), intent(in) :: slist + type(stringlist_type), intent(in) :: slist integer :: i integer :: idxn, idxnew idxn = idx - call insert_empty_positions( list, idxn, slist%size ) + call insert_empty_positions( list, idxn, len(list) ) - do i = 1, slist%size - idxnew = max( 1, idxn ) + i - 1 - list%string(idxnew)%value = slist%string(i)%value - enddo + do i = 1, len(list) + idxnew = idxn + i - 1 + list%stringarray(idxnew) = slist%stringarray(i) + end do end subroutine insert_stringlist_int_impl +! insert_chararray_int_impl -- +! Insert an array of chars into the list - specific implementatinon +! +subroutine insert_chararray_int_impl( list, idx, sarray ) + type(stringlist_type), intent(inout) :: list + integer, intent(in) :: idx + character(len=*), dimension(:), intent(in) :: sarray + + integer :: i + integer :: idxn, idxnew + + idxn = idx + call insert_empty_positions( list, idxn, size(sarray) ) + + do i = 1, size(sarray) + idxnew = idxn + i - 1 + list%stringarray(idxnew) = string_type(sarray(i)) + end do + +end subroutine insert_chararray_int_impl + ! insert_stringarray_int_impl -- ! Insert an array of strings into the list - specific implementatinon ! subroutine insert_stringarray_int_impl( list, idx, sarray ) - class(stringlist_type), intent(inout) :: list + type(stringlist_type), intent(inout) :: list integer, intent(in) :: idx - character(len=*), dimension(:), intent(in) :: sarray + type(string_type), dimension(:), intent(in) :: sarray integer :: i integer :: idxn, idxnew @@ -415,9 +485,9 @@ subroutine insert_stringarray_int_impl( list, idx, sarray ) call insert_empty_positions( list, idxn, size(sarray) ) do i = 1, size(sarray) - idxnew = max( 1, idxn ) + i - 1 - list%string(idxnew)%value = sarray(i) - enddo + idxnew = idxn + i - 1 + list%stringarray(idxnew) = sarray(i) + end do end subroutine insert_stringarray_int_impl @@ -428,570 +498,574 @@ end subroutine insert_stringarray_int_impl ! list The list of strings to retrieve the string from ! idx Index after which to insert the string ! -function get_string_idx_wrap( list, idx ) - class(stringlist_type), intent(in) :: list +pure function get_string_idx_wrap( list, idx ) + type(stringlist_type), intent(in) :: list type(stringlist_index_type), intent(in) :: idx - character(len=:), allocatable :: get_string_idx_wrap + type(string_type) :: get_string_idx_wrap - integer :: idxabs + get_string_idx_wrap = list%get( to_idxn(idx) ) - idxabs = merge( idx%offset, list%size + idx%offset, idx%head ) - - get_string_idx_wrap = list%get( idxabs ) end function get_string_idx_wrap -function get_string_int_impl( list, idx ) - class(stringlist_type), intent(in) :: list +pure function get_string_int_impl( list, idx ) + type(stringlist_type), intent(in) :: list integer, intent(in) :: idx - character(len=:), allocatable :: get_string_int_impl + type(string_type) :: get_string_int_impl integer :: idxnew ! ! Examine the actual index: - ! - if the index is larger than the size, return an empty string - ! - if the index is equal to list_head, interpret it as index 1 - ! - if the index is negative, calculate the absolute index + ! - if the index is out of bounds, return a string_type equivalent to empty string ! - if ( idx > list%size .or. idx < 1 ) then - get_string_int_impl = '' - else - get_string_int_impl = list%string(idx)%value - endif -end function get_string_int_impl - -! sort_list -- -! Sort the list and return the result as a new list -! -! Arguments: -! list The list of strings to retrieve the string from -! ascending Whether to sort as ascending (true) or not (false) -! -function sort_list( list, ascending ) - class(stringlist_type), intent(in) :: list - logical, intent(in), optional :: ascending - - integer :: i - integer, dimension(:), allocatable :: idx - class(stringlist_type), allocatable :: sort_list - logical :: ascending_order - - ! - ! Allocate and fill the index array, then sort the indices - ! based on the strings - ! - idx = [ (i ,i=1,list%size) ] - - ascending_order = .true. - if ( present(ascending) ) then - ascending_order = ascending - endif - - if ( ascending_order ) then - idx = sort_ascending( idx ) - else - idx = sort_descending( idx ) - endif - - allocate( sort_list ) - allocate( sort_list%string(list%size) ) - - do i = 1,list%size - sort_list%string(i) = list%string(idx(i)) - enddo - sort_list%size = list%size - -contains -recursive function sort_ascending( idx ) result(idxnew) - integer, dimension(:) :: idx - integer, dimension(size(idx)) :: idxnew - - if ( size(idx) > 1 ) then - idxnew = [ sort_ascending( pack( idx, list%string(idx) < list%string(idx(1)) ) ), & - pack( idx, list%string(idx) == list%string(idx(1)) ) , & - sort_ascending( pack( idx, list%string(idx) > list%string(idx(1)) ) ) ] - else - idxnew = idx - endif -end function sort_ascending - -recursive function sort_descending( idx ) result(idxnew) - integer, dimension(:) :: idx - integer, dimension(size(idx)) :: idxnew - - if ( size(idx) > 1 ) then - idxnew = [ sort_descending( pack( idx, list%string(idx) > list%string(idx(1)) ) ), & - pack( idx, list%string(idx) == list%string(idx(1)) ) , & - sort_descending( pack( idx, list%string(idx) < list%string(idx(1)) ) ) ] - else - idxnew = idx - endif -end function sort_descending - -end function sort_list - -! index_of_string -- -! Return the index in the list of a particular string -! -! Arguments: -! list The list of strings in which to search the string -! string The string to be found -! back Whether to search from the end (true) or not (false, default) -! -integer function index_of_string( list, string, back ) - class(stringlist_type), intent(in) :: list - character(len=*), intent(in) :: string - logical, intent(in), optional :: back - - integer :: idx - integer :: i - logical :: start_backwards - - start_backwards = .false. - if ( present(back) ) then - start_backwards = back - endif - - idx = 0 - if ( start_backwards) then - do i = list%size,1,-1 - if ( list%string(i)%value == string ) then - idx = i - exit - endif - enddo - else - do i = 1,list%size - if ( list%string(i)%value == string ) then - idx = i - exit - endif - enddo - endif - - index_of_string = idx -end function index_of_string - -! index_of_substring -- -! Return the index in the list of a string containing a particular substring -! -! Arguments: -! list The list of strings in which to search the string -! substring The substring to be found -! back Whether to search from the end (true) or not (false, default) -! -integer function index_of_substring( list, substring, back ) - class(stringlist_type), intent(in) :: list - character(len=*), intent(in) :: substring - logical, intent(in), optional :: back - - integer :: idx - integer :: i - logical :: start_backwards - - start_backwards = .false. - if ( present(back) ) then - start_backwards = back - endif - - idx = 0 - if ( start_backwards) then - do i = list%size,1,-1 - if ( index(list%string(i)%value, substring) > 0 ) then - idx = i - exit - endif - enddo - else - do i = 1,list%size - if ( index(list%string(i)%value, substring) > 0 ) then - idx = i - exit - endif - enddo - endif - - index_of_substring = idx -end function index_of_substring - -! delete_strings -- -! Delete one or more strings from the list -! -! Arguments: -! list The list of strings in which to search the string -! first The position of the first string to be deleted -! last The position of the last string to be deleted -! -! Note: -! If the range defined by first and last has a zero length or first > last, -! then nothing happens. -! -subroutine delete_strings_idx_idx_wrap( list, first, last ) - class(stringlist_type), intent(inout) :: list - type(stringlist_index_type), intent(in) :: first - type(stringlist_index_type), intent(in) :: last - - integer :: firstpos - integer :: lastpos - - firstpos = merge( first%offset, list%size + first%offset, first%head ) - lastpos = merge( last%offset, list%size + last%offset, last%head ) - - call list%delete( firstpos, lastpos ) -end subroutine delete_strings_idx_idx_wrap - -subroutine delete_strings_int_idx_wrap( list, first, last ) - class(stringlist_type), intent(inout) :: list - integer, intent(in) :: first - type(stringlist_index_type), intent(in) :: last + if ( 1 <= idx .or. idx <= len(list) ) then + get_string_int_impl = list%stringarray(idx) + end if - integer :: firstpos - integer :: lastpos - - lastpos = merge( last%offset, list%size + last%offset, last%head ) - - call list%delete( firstpos, lastpos ) -end subroutine delete_strings_int_idx_wrap - -subroutine delete_strings_idx_int_wrap( list, first, last ) - class(stringlist_type), intent(inout) :: list - type(stringlist_index_type), intent(in) :: first - integer, intent(in) :: last - - integer :: firstpos - integer :: lastpos - - firstpos = merge( first%offset, list%size + first%offset, first%head ) - - call list%delete( firstpos, lastpos ) -end subroutine delete_strings_idx_int_wrap - -subroutine delete_strings_int_int_impl( list, first, last ) - class(stringlist_type), intent(inout) :: list - integer, intent(in) :: first - integer, intent(in) :: last - - integer :: firstpos - integer :: lastpos - integer :: i - integer :: j - - if ( first > list%size .or. last < 1 ) then - return - endif - - firstpos = max( 1, min(list%size, first ) ) - lastpos = max( 1, min(list%size, last ) ) - - if ( firstpos > lastpos ) then - return - else - do i = lastpos+1,list%size - j = firstpos + i - lastpos - 1 - call move_alloc( list%string(i)%value, list%string(j)%value ) - enddo - do i = list%size - (lastpos-firstpos), list%size - list%string(i)%value = '' - enddo - - list%size = list%size - (lastpos-firstpos + 1) - endif -end subroutine delete_strings_int_int_impl - -! range_list -- -! Return a sublist given by the first and last position -! -! Arguments: -! list The list of strings in which to search the string -! first The position of the first string to be deleted -! last The position of the last string to be deleted -! -! Note: -! If the range defined by first and last has a zero length or first > last, -! then return an empty list -! -function range_list_idx_idx_wrap( list, first, last ) - class(stringlist_type), intent(inout) :: list - type(stringlist_index_type), intent(in) :: first - type(stringlist_index_type), intent(in) :: last - class(stringlist_type), allocatable :: range_list_idx_idx_wrap - - integer :: firstpos - integer :: lastpos - - firstpos = merge( first%offset, list%size + first%offset, first%head ) - lastpos = merge( last%offset, list%size + last%offset, last%head ) - - range_list_idx_idx_wrap = list%range( firstpos, lastpos ) - -end function range_list_idx_idx_wrap - -function range_list_int_idx_wrap( list, first, last ) - class(stringlist_type), intent(inout) :: list - integer, intent(in) :: first - type(stringlist_index_type), intent(in) :: last - class(stringlist_type), allocatable :: range_list_int_idx_wrap +end function get_string_int_impl - integer :: lastpos +! ! sort_list -- +! ! Sort the list and return the result as a new list +! ! +! ! Arguments: +! ! list The list of strings to retrieve the string from +! ! ascending Whether to sort as ascending (true) or not (false) +! ! +! function sort_list( list, ascending ) +! class(stringlist_type), intent(in) :: list +! logical, intent(in), optional :: ascending + +! integer :: i +! integer, dimension(:), allocatable :: idx +! class(stringlist_type), allocatable :: sort_list +! logical :: ascending_order + +! ! +! ! Allocate and fill the index array, then sort the indices +! ! based on the strings +! ! +! idx = [ (i ,i=1,list%size) ] + +! ascending_order = .true. +! if ( present(ascending) ) then +! ascending_order = ascending +! endif + +! if ( ascending_order ) then +! idx = sort_ascending( idx ) +! else +! idx = sort_descending( idx ) +! endif + +! allocate( sort_list ) +! allocate( sort_list%string(list%size) ) + +! do i = 1,list%size +! sort_list%string(i) = list%string(idx(i)) +! enddo +! sort_list%size = list%size + +! contains +! recursive function sort_ascending( idx ) result(idxnew) +! integer, dimension(:) :: idx +! integer, dimension(size(idx)) :: idxnew + +! if ( size(idx) > 1 ) then +! idxnew = [ sort_ascending( pack( idx, list%string(idx) < list%string(idx(1)) ) ), & +! pack( idx, list%string(idx) == list%string(idx(1)) ) , & +! sort_ascending( pack( idx, list%string(idx) > list%string(idx(1)) ) ) ] +! else +! idxnew = idx +! endif +! end function sort_ascending + +! recursive function sort_descending( idx ) result(idxnew) +! integer, dimension(:) :: idx +! integer, dimension(size(idx)) :: idxnew + +! if ( size(idx) > 1 ) then +! idxnew = [ sort_descending( pack( idx, list%string(idx) > list%string(idx(1)) ) ), & +! pack( idx, list%string(idx) == list%string(idx(1)) ) , & +! sort_descending( pack( idx, list%string(idx) < list%string(idx(1)) ) ) ] +! else +! idxnew = idx +! endif +! end function sort_descending + +! end function sort_list + +! ! index_of_char -- +! ! Return the index in the list of a particular string +! ! +! ! Arguments: +! ! list The list of strings in which to search the string +! ! string The string to be found +! ! back Whether to search from the end (true) or not (false, default) +! ! +! integer function index_of_char( list, string, back ) +! class(stringlist_type), intent(in) :: list +! character(len=*), intent(in) :: string +! logical, intent(in), optional :: back + +! integer :: idx +! integer :: i, first, last, stride + +! if ( optval(back, .false.) ) then +! first = list%size +! last = 1 +! stride = -1 +! else +! first = 1 +! last = list%size +! stride = 1 +! end if + +! idx = 0 +! do i = first, last, stride +! if ( list%stringarray(i) == string ) then +! idx = i +! exit +! end if +! end do + +! index_of_string = idx + +! end function index_of_char + +! integer function index_of_string( list, string, back ) +! class(stringlist_type), intent(in) :: list +! type(string_type), intent(in) :: string +! logical, intent(in), optional :: back + +! index_of_string = index_of_char(list, char(string), back) + +! end function index_of_string + +! ! index_of_substring -- +! ! Return the index in the list of a string containing a particular substring +! ! +! ! Arguments: +! ! list The list of strings in which to search the string +! ! substring The substring to be found +! ! back Whether to search from the end (true) or not (false, default) +! ! +! integer function index_of_subchar( list, substring, back ) +! class(stringlist_type), intent(in) :: list +! character(len=*), intent(in) :: substring +! logical, intent(in), optional :: back + +! integer :: idx +! integer :: i, first, last, stride + +! if ( optval(back, .false.) ) then +! first = list%size +! last = 1 +! stride = -1 +! else +! first = 1 +! last = list%size +! stride = 1 +! end if + +! idx = 0 +! do i = first, last, stride +! if ( find( list%stringarray(i), substring ) > 0 ) then +! idx = i +! exit +! end if +! end do + +! index_of_substring = idx + +! end function index_of_subchar + +! integer function index_of_substring( list, string, back ) +! class(stringlist_type), intent(in) :: list +! type(string_type), intent(in) :: string +! logical, intent(in), optional :: back + +! index_of_substring = index_of_subchar(list, char(string), back) + +! end function index_of_substring + +! ! delete_strings -- +! ! Delete one or more strings from the list +! ! +! ! Arguments: +! ! list The list of strings in which to search the string +! ! first The position of the first string to be deleted +! ! last The position of the last string to be deleted +! ! +! ! Note: +! ! If the range defined by first and last has a zero length or first > last, +! ! then nothing happens. +! ! +! subroutine delete_strings_idx_idx_wrap( list, first, last ) +! class(stringlist_type), intent(inout) :: list +! type(stringlist_index_type), intent(in) :: first +! type(stringlist_index_type), intent(in) :: last + +! integer :: firstpos +! integer :: lastpos + +! firstpos = merge( first%offset, list%size + first%offset, first%head ) +! lastpos = merge( last%offset, list%size + last%offset, last%head ) + +! call list%delete( firstpos, lastpos ) +! end subroutine delete_strings_idx_idx_wrap + +! subroutine delete_strings_int_idx_wrap( list, first, last ) +! class(stringlist_type), intent(inout) :: list +! integer, intent(in) :: first +! type(stringlist_index_type), intent(in) :: last + +! integer :: firstpos +! integer :: lastpos + +! lastpos = merge( last%offset, list%size + last%offset, last%head ) + +! call list%delete( firstpos, lastpos ) +! end subroutine delete_strings_int_idx_wrap + +! subroutine delete_strings_idx_int_wrap( list, first, last ) +! class(stringlist_type), intent(inout) :: list +! type(stringlist_index_type), intent(in) :: first +! integer, intent(in) :: last + +! integer :: firstpos +! integer :: lastpos + +! firstpos = merge( first%offset, list%size + first%offset, first%head ) + +! call list%delete( firstpos, lastpos ) +! end subroutine delete_strings_idx_int_wrap + +! subroutine delete_strings_int_int_impl( list, first, last ) +! class(stringlist_type), intent(inout) :: list +! integer, intent(in) :: first +! integer, intent(in) :: last + +! integer :: firstpos +! integer :: lastpos +! integer :: i +! integer :: j + +! if ( first > list%size .or. last < 1 ) then +! return +! endif + +! firstpos = max( 1, min(list%size, first ) ) +! lastpos = max( 1, min(list%size, last ) ) + +! if ( firstpos > lastpos ) then +! return +! else +! do i = lastpos+1,list%size +! j = firstpos + i - lastpos - 1 +! call move_alloc( list%string(i)%value, list%string(j)%value ) +! enddo +! do i = list%size - (lastpos-firstpos), list%size +! list%string(i)%value = '' +! enddo + +! list%size = list%size - (lastpos-firstpos + 1) +! endif +! end subroutine delete_strings_int_int_impl + +! ! range_list -- +! ! Return a sublist given by the first and last position +! ! +! ! Arguments: +! ! list The list of strings in which to search the string +! ! first The position of the first string to be deleted +! ! last The position of the last string to be deleted +! ! +! ! Note: +! ! If the range defined by first and last has a zero length or first > last, +! ! then return an empty list +! ! +! function range_list_idx_idx_wrap( list, first, last ) +! class(stringlist_type), intent(inout) :: list +! type(stringlist_index_type), intent(in) :: first +! type(stringlist_index_type), intent(in) :: last +! class(stringlist_type), allocatable :: range_list_idx_idx_wrap + +! integer :: firstpos +! integer :: lastpos + +! firstpos = merge( first%offset, list%size + first%offset, first%head ) +! lastpos = merge( last%offset, list%size + last%offset, last%head ) + +! range_list_idx_idx_wrap = list%range( firstpos, lastpos ) + +! end function range_list_idx_idx_wrap + +! function range_list_int_idx_wrap( list, first, last ) +! class(stringlist_type), intent(inout) :: list +! integer, intent(in) :: first +! type(stringlist_index_type), intent(in) :: last +! class(stringlist_type), allocatable :: range_list_int_idx_wrap - lastpos = merge( last%offset, list%size + last%offset, last%head ) +! integer :: lastpos - range_list_int_idx_wrap = list%range( first, lastpos ) +! lastpos = merge( last%offset, list%size + last%offset, last%head ) -end function range_list_int_idx_wrap +! range_list_int_idx_wrap = list%range( first, lastpos ) + +! end function range_list_int_idx_wrap + +! function range_list_idx_int_wrap( list, first, last ) +! class(stringlist_type), intent(inout) :: list +! type(stringlist_index_type), intent(in) :: first +! integer, intent(in) :: last +! class(stringlist_type), allocatable :: range_list_idx_int_wrap -function range_list_idx_int_wrap( list, first, last ) - class(stringlist_type), intent(inout) :: list - type(stringlist_index_type), intent(in) :: first - integer, intent(in) :: last - class(stringlist_type), allocatable :: range_list_idx_int_wrap +! integer :: firstpos - integer :: firstpos +! firstpos = merge( first%offset, list%size + first%offset, first%head ) - firstpos = merge( first%offset, list%size + first%offset, first%head ) +! range_list_idx_int_wrap = list%range( firstpos, last ) + +! end function range_list_idx_int_wrap + +! function range_list_int_int_impl( list, first, last ) +! class(stringlist_type), intent(inout) :: list +! integer, intent(in) :: first +! integer, intent(in) :: last +! class(stringlist_type), allocatable :: range_list_int_int_impl - range_list_idx_int_wrap = list%range( firstpos, last ) +! integer :: firstpos +! integer :: lastpos -end function range_list_idx_int_wrap +! allocate( range_list_int_int_impl ) + +! if ( first > list%size .or. last < 1 ) then +! allocate( range_list_int_int_impl%string(0) ) +! return +! endif + +! firstpos = max( 1, min(list%size, first ) ) +! lastpos = max( 1, min(list%size, last ) ) + +! if ( firstpos > lastpos ) then +! allocate( range_list_int_int_impl%string(0) ) +! return +! else +! range_list_int_int_impl%size = lastpos - firstpos + 1 +! range_list_int_int_impl%string = list%string(firstpos:lastpos) +! endif +! end function range_list_int_int_impl + + +! ! replace_string -- +! ! Replace a string in the list +! ! +! ! Arguments: +! ! list The list of strings in which to replace a string (or a range of strings) +! ! first First index of the string(s) to be replaced +! ! last Last index of the string(s) to be replaced +! ! string The string in question (array of strings or another string list) +! ! +! ! Note: +! ! For convenience a version that simply replaces a single string is provided +! ! +! subroutine replace_string_idx_wrap( list, idx, string ) +! class(stringlist_type), intent(inout) :: list +! type(stringlist_index_type), intent(in) :: idx +! character(len=*), intent(in) :: string -function range_list_int_int_impl( list, first, last ) - class(stringlist_type), intent(inout) :: list - integer, intent(in) :: first - integer, intent(in) :: last - class(stringlist_type), allocatable :: range_list_int_int_impl +! integer :: idxpos - integer :: firstpos - integer :: lastpos +! idxpos = merge( idx%offset, list%size + idx%offset, idx%head ) - allocate( range_list_int_int_impl ) +! call list%replace( idxpos, string ) +! end subroutine replace_string_idx_wrap - if ( first > list%size .or. last < 1 ) then - allocate( range_list_int_int_impl%string(0) ) - return - endif +! subroutine replace_string_int_impl( list, idx, string ) +! class(stringlist_type), intent(inout) :: list +! integer, intent(in) :: idx +! character(len=*), intent(in) :: string - firstpos = max( 1, min(list%size, first ) ) - lastpos = max( 1, min(list%size, last ) ) +! integer :: idxpos - if ( firstpos > lastpos ) then - allocate( range_list_int_int_impl%string(0) ) - return - else - range_list_int_int_impl%size = lastpos - firstpos + 1 - range_list_int_int_impl%string = list%string(firstpos:lastpos) - endif -end function range_list_int_int_impl +! if ( idx < 1 .or. idx > list%size ) then +! return +! endif +! list%string(idx)%value = string +! end subroutine replace_string_int_impl -! replace_string -- -! Replace a string in the list -! -! Arguments: -! list The list of strings in which to replace a string (or a range of strings) -! first First index of the string(s) to be replaced -! last Last index of the string(s) to be replaced -! string The string in question (array of strings or another string list) -! -! Note: -! For convenience a version that simply replaces a single string is provided -! -subroutine replace_string_idx_wrap( list, idx, string ) - class(stringlist_type), intent(inout) :: list - type(stringlist_index_type), intent(in) :: idx - character(len=*), intent(in) :: string +! subroutine replace_string_idx_idx_wrap( list, first, last, string ) +! class(stringlist_type), intent(inout) :: list +! type(stringlist_index_type), intent(in) :: first +! type(stringlist_index_type), intent(in) :: last +! character(len=*), intent(in) :: string - integer :: idxpos +! integer :: firstpos, lastpos - idxpos = merge( idx%offset, list%size + idx%offset, idx%head ) +! firstpos = merge( first%offset, list%size + first%offset, first%head ) +! lastpos = merge( last%offset, list%size + last%offset, last%head ) - call list%replace( idxpos, string ) -end subroutine replace_string_idx_wrap +! call list%replace( firstpos, lastpos, string ) +! end subroutine replace_string_idx_idx_wrap -subroutine replace_string_int_impl( list, idx, string ) - class(stringlist_type), intent(inout) :: list - integer, intent(in) :: idx - character(len=*), intent(in) :: string +! subroutine replace_string_int_idx_wrap( list, first, last, string ) +! class(stringlist_type), intent(inout) :: list +! integer, intent(in) :: first +! type(stringlist_index_type), intent(in) :: last +! character(len=*), intent(in) :: string - integer :: idxpos +! integer :: lastpos - if ( idx < 1 .or. idx > list%size ) then - return - endif +! lastpos = merge( last%offset, list%size + last%offset, last%head ) - list%string(idx)%value = string -end subroutine replace_string_int_impl +! call list%replace( first, lastpos, string ) +! end subroutine replace_string_int_idx_wrap -subroutine replace_string_idx_idx_wrap( list, first, last, string ) - class(stringlist_type), intent(inout) :: list - type(stringlist_index_type), intent(in) :: first - type(stringlist_index_type), intent(in) :: last - character(len=*), intent(in) :: string +! subroutine replace_string_idx_int_wrap( list, first, last, string ) +! class(stringlist_type), intent(inout) :: list +! type(stringlist_index_type), intent(in) :: first +! integer, intent(in) :: last +! character(len=*), intent(in) :: string - integer :: firstpos, lastpos +! integer :: firstpos - firstpos = merge( first%offset, list%size + first%offset, first%head ) - lastpos = merge( last%offset, list%size + last%offset, last%head ) +! firstpos = merge( first%offset, list%size + first%offset, first%head ) - call list%replace( firstpos, lastpos, string ) -end subroutine replace_string_idx_idx_wrap +! call list%replace( firstpos, last, string ) +! end subroutine replace_string_idx_int_wrap -subroutine replace_string_int_idx_wrap( list, first, last, string ) - class(stringlist_type), intent(inout) :: list - integer, intent(in) :: first - type(stringlist_index_type), intent(in) :: last - character(len=*), intent(in) :: string - - integer :: lastpos - - lastpos = merge( last%offset, list%size + last%offset, last%head ) - - call list%replace( first, lastpos, string ) -end subroutine replace_string_int_idx_wrap - -subroutine replace_string_idx_int_wrap( list, first, last, string ) - class(stringlist_type), intent(inout) :: list - type(stringlist_index_type), intent(in) :: first - integer, intent(in) :: last - character(len=*), intent(in) :: string - - integer :: firstpos - - firstpos = merge( first%offset, list%size + first%offset, first%head ) - - call list%replace( firstpos, last, string ) -end subroutine replace_string_idx_int_wrap - -subroutine replace_string_int_int_impl( list, first, last, string ) - class(stringlist_type), intent(inout) :: list - integer, intent(in) :: first - integer, intent(in) :: last - character(len=*), intent(in) :: string +! subroutine replace_string_int_int_impl( list, first, last, string ) +! class(stringlist_type), intent(inout) :: list +! integer, intent(in) :: first +! integer, intent(in) :: last +! character(len=*), intent(in) :: string - if ( first > list%size .or. last < 1 ) then - return - endif - if ( first > last ) then - return - endif +! if ( first > list%size .or. last < 1 ) then +! return +! endif +! if ( first > last ) then +! return +! endif - call list%delete( first, last ) - call list%insert( first, string ) -end subroutine replace_string_int_int_impl +! call list%delete( first, last ) +! call list%insert( first, string ) +! end subroutine replace_string_int_int_impl -subroutine replace_stringlist_idx_idx_wrap( list, first, last, slist ) - class(stringlist_type), intent(inout) :: list - type(stringlist_index_type), intent(in) :: first - type(stringlist_index_type), intent(in) :: last - class(stringlist_type), intent(in) :: slist +! subroutine replace_stringlist_idx_idx_wrap( list, first, last, slist ) +! class(stringlist_type), intent(inout) :: list +! type(stringlist_index_type), intent(in) :: first +! type(stringlist_index_type), intent(in) :: last +! class(stringlist_type), intent(in) :: slist - integer :: firstpos, lastpos +! integer :: firstpos, lastpos - firstpos = merge( first%offset, list%size + first%offset, first%head ) - lastpos = merge( last%offset, list%size + last%offset, last%head ) +! firstpos = merge( first%offset, list%size + first%offset, first%head ) +! lastpos = merge( last%offset, list%size + last%offset, last%head ) - call list%replace( firstpos, lastpos, slist ) -end subroutine replace_stringlist_idx_idx_wrap +! call list%replace( firstpos, lastpos, slist ) +! end subroutine replace_stringlist_idx_idx_wrap -subroutine replace_stringlist_int_idx_wrap( list, first, last, slist ) - class(stringlist_type), intent(inout) :: list - integer, intent(in) :: first - type(stringlist_index_type), intent(in) :: last - class(stringlist_type), intent(in) :: slist +! subroutine replace_stringlist_int_idx_wrap( list, first, last, slist ) +! class(stringlist_type), intent(inout) :: list +! integer, intent(in) :: first +! type(stringlist_index_type), intent(in) :: last +! class(stringlist_type), intent(in) :: slist - integer :: lastpos +! integer :: lastpos - lastpos = merge( last%offset, list%size + last%offset, last%head ) +! lastpos = merge( last%offset, list%size + last%offset, last%head ) - call list%replace( first, lastpos, slist ) -end subroutine replace_stringlist_int_idx_wrap +! call list%replace( first, lastpos, slist ) +! end subroutine replace_stringlist_int_idx_wrap -subroutine replace_stringlist_idx_int_wrap( list, first, last, slist ) - class(stringlist_type), intent(inout) :: list - type(stringlist_index_type), intent(in) :: first - integer, intent(in) :: last - class(stringlist_type), intent(in) :: slist +! subroutine replace_stringlist_idx_int_wrap( list, first, last, slist ) +! class(stringlist_type), intent(inout) :: list +! type(stringlist_index_type), intent(in) :: first +! integer, intent(in) :: last +! class(stringlist_type), intent(in) :: slist - integer :: firstpos +! integer :: firstpos - firstpos = merge( first%offset, list%size + first%offset, first%head ) +! firstpos = merge( first%offset, list%size + first%offset, first%head ) - call list%replace( firstpos, last, slist ) -end subroutine replace_stringlist_idx_int_wrap +! call list%replace( firstpos, last, slist ) +! end subroutine replace_stringlist_idx_int_wrap -subroutine replace_stringlist_int_int_impl( list, first, last, slist ) - class(stringlist_type), intent(inout) :: list - integer, intent(in) :: first - integer, intent(in) :: last - class(stringlist_type), intent(in) :: slist +! subroutine replace_stringlist_int_int_impl( list, first, last, slist ) +! class(stringlist_type), intent(inout) :: list +! integer, intent(in) :: first +! integer, intent(in) :: last +! class(stringlist_type), intent(in) :: slist - if ( first > list%size .or. last < 1 ) then - return - endif - if ( first > last ) then - return - endif +! if ( first > list%size .or. last < 1 ) then +! return +! endif +! if ( first > last ) then +! return +! endif - call list%delete( first, last ) - call list%insert( first, slist ) -end subroutine replace_stringlist_int_int_impl +! call list%delete( first, last ) +! call list%insert( first, slist ) +! end subroutine replace_stringlist_int_int_impl -subroutine replace_stringarray_idx_idx_wrap( list, first, last, sarray ) - class(stringlist_type), intent(inout) :: list - type(stringlist_index_type), intent(in) :: first - type(stringlist_index_type), intent(in) :: last - character(len=*), dimension(:), intent(in) :: sarray +! subroutine replace_stringarray_idx_idx_wrap( list, first, last, sarray ) +! class(stringlist_type), intent(inout) :: list +! type(stringlist_index_type), intent(in) :: first +! type(stringlist_index_type), intent(in) :: last +! character(len=*), dimension(:), intent(in) :: sarray - integer :: firstpos, lastpos +! integer :: firstpos, lastpos - firstpos = merge( first%offset, list%size + first%offset, first%head ) - lastpos = merge( last%offset, list%size + last%offset, last%head ) +! firstpos = merge( first%offset, list%size + first%offset, first%head ) +! lastpos = merge( last%offset, list%size + last%offset, last%head ) - call list%replace( firstpos, lastpos, sarray ) -end subroutine replace_stringarray_idx_idx_wrap +! call list%replace( firstpos, lastpos, sarray ) +! end subroutine replace_stringarray_idx_idx_wrap -subroutine replace_stringarray_int_idx_wrap( list, first, last, sarray ) - class(stringlist_type), intent(inout) :: list - integer, intent(in) :: first - type(stringlist_index_type), intent(in) :: last - character(len=*), dimension(:), intent(in) :: sarray +! subroutine replace_stringarray_int_idx_wrap( list, first, last, sarray ) +! class(stringlist_type), intent(inout) :: list +! integer, intent(in) :: first +! type(stringlist_index_type), intent(in) :: last +! character(len=*), dimension(:), intent(in) :: sarray - integer :: lastpos +! integer :: lastpos - lastpos = merge( last%offset, list%size + last%offset, last%head ) +! lastpos = merge( last%offset, list%size + last%offset, last%head ) - call list%replace( first, lastpos, sarray ) -end subroutine replace_stringarray_int_idx_wrap +! call list%replace( first, lastpos, sarray ) +! end subroutine replace_stringarray_int_idx_wrap -subroutine replace_stringarray_idx_int_wrap( list, first, last, sarray ) - class(stringlist_type), intent(inout) :: list - type(stringlist_index_type), intent(in) :: first - integer, intent(in) :: last - character(len=*), dimension(:), intent(in) :: sarray +! subroutine replace_stringarray_idx_int_wrap( list, first, last, sarray ) +! class(stringlist_type), intent(inout) :: list +! type(stringlist_index_type), intent(in) :: first +! integer, intent(in) :: last +! character(len=*), dimension(:), intent(in) :: sarray - integer :: firstpos +! integer :: firstpos - firstpos = merge( first%offset, list%size + first%offset, first%head ) +! firstpos = merge( first%offset, list%size + first%offset, first%head ) - call list%replace( firstpos, last, sarray ) -end subroutine replace_stringarray_idx_int_wrap +! call list%replace( firstpos, last, sarray ) +! end subroutine replace_stringarray_idx_int_wrap -subroutine replace_stringarray_int_int_impl( list, first, last, sarray ) - class(stringlist_type), intent(inout) :: list - integer, intent(in) :: first - integer, intent(in) :: last - character(len=*), dimension(:), intent(in) :: sarray +! subroutine replace_stringarray_int_int_impl( list, first, last, sarray ) +! class(stringlist_type), intent(inout) :: list +! integer, intent(in) :: first +! integer, intent(in) :: last +! character(len=*), dimension(:), intent(in) :: sarray - if ( first > list%size .or. last < 1 ) then - return - endif - if ( first > last ) then - return - endif +! if ( first > list%size .or. last < 1 ) then +! return +! endif +! if ( first > last ) then +! return +! endif - call list%delete( first, last ) - call list%insert( first, sarray ) -end subroutine replace_stringarray_int_int_impl +! call list%delete( first, last ) +! call list%insert( first, sarray ) +! end subroutine replace_stringarray_int_int_impl end module stdlib_stringlist From e7604bd8735f53bbeb871d1408547b023a108423 Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Sat, 24 Jul 2021 12:52:32 +0530 Subject: [PATCH 05/40] resolved stash conflicts --- src/stdlib_stringlist.f90 | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/stdlib_stringlist.f90 b/src/stdlib_stringlist.f90 index 80e104ed1..6c380c593 100644 --- a/src/stdlib_stringlist.f90 +++ b/src/stdlib_stringlist.f90 @@ -218,21 +218,13 @@ pure function prepend_string( string, list ) end function prepend_string -<<<<<<< Updated upstream -function append_stringlist( list, slist ) -======= pure function append_stringlist( list, slist ) ->>>>>>> Stashed changes type(stringlist_type), intent(in) :: list type(stringlist_type), intent(in) :: slist type(stringlist_type) :: append_stringlist append_stringlist = list -<<<<<<< Updated upstream - call append_stringlist%insert( list_after_end, slist ) -======= call append_stringlist%insert( list_tail, slist ) ->>>>>>> Stashed changes end function append_stringlist From bc9eda7a9381dbde6c22c8216b37ce447d045e3a Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Sat, 24 Jul 2021 18:55:15 +0530 Subject: [PATCH 06/40] resolved 2 bugs, improved aesthetics of code --- src/stdlib_stringlist.f90 | 92 +++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/src/stdlib_stringlist.f90 b/src/stdlib_stringlist.f90 index 6c380c593..e4eb9a2de 100644 --- a/src/stdlib_stringlist.f90 +++ b/src/stdlib_stringlist.f90 @@ -280,8 +280,8 @@ pure integer function capacity( list ) type(stringlist_type), intent(in) :: list capacity = 0 - if ( allocated(list%stringarray) ) then - capacity = size(list%stringarray) + if ( allocated( list%stringarray ) ) then + capacity = size( list%stringarray ) end if end function capacity @@ -304,38 +304,38 @@ end function to_idxn ! string The string in question ! subroutine insert_char_idx_wrap( list, idx, string ) - type(stringlist_type), intent(inout) :: list - type(stringlist_index_type), intent(in) :: idx - character(len=*), intent(in) :: string + type(stringlist_type), intent(inout) :: list + type(stringlist_index_type), intent(in) :: idx + character(len=*), intent(in) :: string call list%insert( idx, string_type( string ) ) end subroutine insert_char_idx_wrap subroutine insert_string_idx_wrap( list, idx, string ) - type(stringlist_type), intent(inout) :: list - type(stringlist_index_type), intent(in) :: idx - type(type_string), intent(in) :: string + type(stringlist_type), intent(inout) :: list + type(stringlist_index_type), intent(in) :: idx + type(string_type), intent(in) :: string - call list%insert( to_idxn(idx), string ) + call list%insert( to_idxn( idx ), string ) end subroutine insert_string_idx_wrap subroutine insert_stringlist_idx_wrap( list, idx, slist ) - type(stringlist_type), intent(inout) :: list - type(stringlist_index_type), intent(in) :: idx - type(stringlist_type), intent(in) :: slist + type(stringlist_type), intent(inout) :: list + type(stringlist_index_type), intent(in) :: idx + type(stringlist_type), intent(in) :: slist - call list%insert( to_idxn(idx), slist ) + call list%insert( to_idxn( idx ), slist ) end subroutine insert_stringlist_idx_wrap subroutine insert_stringarray_idx_wrap( list, idx, sarray ) - type(stringlist_type), intent(inout) :: list - type(stringlist_index_type), intent(in) :: idx - character(len=*), dimension(:), intent(in) :: sarray + type(stringlist_type), intent(inout) :: list + type(stringlist_index_type), intent(in) :: idx + character(len=*), dimension(:), intent(in) :: sarray - call list%insert( to_idxn(idx), sarray ) + call list%insert( to_idxn( idx ), sarray ) end subroutine insert_stringarray_idx_wrap @@ -348,13 +348,13 @@ end subroutine insert_stringarray_idx_wrap ! number Number of positions ! subroutine insert_empty_positions( list, idxn, number ) - type(stringlist_type), intent(inout) :: list - integer, intent(inout) :: idxn - integer, intent(inout) :: number + type(stringlist_type), intent(inout) :: list + integer, intent(inout) :: idxn + integer, intent(inout) :: number - integer :: i, inew - integer :: new_size, old_size - type(string_type), dimension(:), allocatable :: new_stringarray + integer :: i, inew + integer :: new_size, old_size + type(string_type), dimension(:), allocatable :: new_stringarray if (number > 0) then @@ -395,11 +395,11 @@ end subroutine insert_empty_positions ! Insert a new string into the list - specific implementation ! subroutine insert_char_int_impl( list, idx, string ) - type(stringlist_type), intent(inout) :: list - integer, intent(in) :: idx - character(len=*), intent(in) :: string + type(stringlist_type), intent(inout) :: list + integer, intent(in) :: idx + character(len=*), intent(in) :: string - call insert( list, idx, string_type(string) ) + call insert( list, idx, string_type( string ) ) end subroutine insert_char_int_impl @@ -407,11 +407,11 @@ end subroutine insert_char_int_impl ! Insert a new string into the list - specific implementation ! subroutine insert_string_int_impl( list, idx, string ) - type(stringlist_type), intent(inout) :: list - integer, intent(in) :: idx - type(string_type), intent(in) :: string + type(stringlist_type), intent(inout) :: list + integer, intent(in) :: idx + type(string_type), intent(in) :: string - integer :: idxn + integer :: idxn idxn = idx call insert_empty_positions( list, idxn, 1 ) @@ -424,17 +424,17 @@ end subroutine insert_string_int_impl ! Insert a list of strings into the list - specific implementation ! subroutine insert_stringlist_int_impl( list, idx, slist ) - type(stringlist_type), intent(inout) :: list - integer, intent(in) :: idx - type(stringlist_type), intent(in) :: slist + type(stringlist_type), intent(inout) :: list + integer, intent(in) :: idx + type(stringlist_type), intent(in) :: slist - integer :: i - integer :: idxn, idxnew + integer :: i + integer :: idxn, idxnew idxn = idx - call insert_empty_positions( list, idxn, len(list) ) + call insert_empty_positions( list, idxn, len( slist ) ) - do i = 1, len(list) + do i = 1, len( slist ) idxnew = idxn + i - 1 list%stringarray(idxnew) = slist%stringarray(i) end do @@ -453,11 +453,11 @@ subroutine insert_chararray_int_impl( list, idx, sarray ) integer :: idxn, idxnew idxn = idx - call insert_empty_positions( list, idxn, size(sarray) ) + call insert_empty_positions( list, idxn, size( sarray ) ) - do i = 1, size(sarray) + do i = 1, size( sarray ) idxnew = idxn + i - 1 - list%stringarray(idxnew) = string_type(sarray(i)) + list%stringarray(idxnew) = string_type( sarray(i) ) end do end subroutine insert_chararray_int_impl @@ -474,9 +474,9 @@ subroutine insert_stringarray_int_impl( list, idx, sarray ) integer :: idxn, idxnew idxn = idx - call insert_empty_positions( list, idxn, size(sarray) ) + call insert_empty_positions( list, idxn, size( sarray ) ) - do i = 1, size(sarray) + do i = 1, size( sarray ) idxnew = idxn + i - 1 list%stringarray(idxnew) = sarray(i) end do @@ -499,9 +499,9 @@ pure function get_string_idx_wrap( list, idx ) end function get_string_idx_wrap -pure function get_string_int_impl( list, idx ) +pure function get_string_int_impl( list, idxn ) type(stringlist_type), intent(in) :: list - integer, intent(in) :: idx + integer, intent(in) :: idxn type(string_type) :: get_string_int_impl integer :: idxnew @@ -510,7 +510,7 @@ pure function get_string_int_impl( list, idx ) ! Examine the actual index: ! - if the index is out of bounds, return a string_type equivalent to empty string ! - if ( 1 <= idx .or. idx <= len(list) ) then + if ( 1 <= idxn .and. idxn <= len( list ) ) then get_string_int_impl = list%stringarray(idx) end if From 5f72c18da60fa3c557ee52a42837fa2b6515a024 Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Wed, 28 Jul 2021 23:37:52 +0530 Subject: [PATCH 07/40] added stringlist.f90 to cmakelists & makefile.manual --- src/CMakeLists.txt | 1 + src/Makefile.manual | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c4f6d76e7..f70d8b65c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -56,6 +56,7 @@ set(SRC stdlib_specialfunctions.f90 stdlib_specialfunctions_legendre.f90 stdlib_quadrature_gauss.f90 + stdlib_stringlist.f90 ${outFiles} ) diff --git a/src/Makefile.manual b/src/Makefile.manual index a12f81255..1d6ae2fb9 100644 --- a/src/Makefile.manual +++ b/src/Makefile.manual @@ -40,6 +40,7 @@ SRC = f18estop.f90 \ stdlib_logger.f90 \ stdlib_quadrature_gauss.f90 \ stdlib_strings.f90 \ + stdlib_stringlist.f90 $(SRCGEN) LIB = libstdlib.a @@ -155,3 +156,6 @@ stdlib_math_linspace.o: \ stdlib_math_logspace.o: \ stdlib_math_linspace.o stdlib_linalg_outer_product.o: stdlib_linalg.o +stdlib_stringlist.o: stdlib_stringtype.o \ + stdlib_math.o \ + stdlib_optval.o From 9bbcdf7c7b1730f84ea8c928ef5adc4af6897c52 Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Thu, 29 Jul 2021 00:24:02 +0530 Subject: [PATCH 08/40] blocked integer indexes, added copy function, added comments, stopped using move function --- src/stdlib_stringlist.f90 | 696 ++++++++++++++++++++++---------------- 1 file changed, 404 insertions(+), 292 deletions(-) diff --git a/src/stdlib_stringlist.f90 b/src/stdlib_stringlist.f90 index e4eb9a2de..622f92c52 100644 --- a/src/stdlib_stringlist.f90 +++ b/src/stdlib_stringlist.f90 @@ -16,26 +16,26 @@ ! Limited to implemented routines ! module stdlib_stringlist - use stdlib_string_type, only: string_type, move, assignment(=) !, char, operator(==) + use stdlib_string_type, only: string_type !, move use stdlib_math, only: clip use stdlib_optval, only: optval implicit none private public :: stringlist_type, operator(//) - public :: list_head, list_tail, fidx, bidx !, operator(+), operator(-) + public :: list_head, list_tail, fidx, bidx, stringlist_index_type !, operator(+), operator(-) type stringlist_index_type private - logical :: head + logical :: forward integer :: offset end type stringlist_index_type - type(stringlist_index_type), parameter :: list_head = forward_index(1) + type(stringlist_index_type), parameter :: list_head = stringlist_index_type( .true. , 1 ) ! fidx(1) + type(stringlist_index_type), parameter :: list_tail = stringlist_index_type( .false., 1 ) ! bidx(1) ! type(stringlist_index_type), parameter :: list_end = stringlist_index_type( .false., 0 ) ! type(stringlist_index_type), parameter :: list_after_end = stringlist_index_type( .false., 1 ) - type(stringlist_index_type), parameter :: list_tail = backward_index(1) ! interface operator(+) ! module procedure stringlist_index_add @@ -45,10 +45,18 @@ module stdlib_stringlist ! module procedure stringlist_index_subtract ! end interface + !> Version: experimental + !> + !> Returns an instance of type 'stringlist_index_type' representing forward index + !> [Specifications](../page/specs/stdlib_stringlist.html#fidx) interface fidx module procedure forward_index end interface + !> Version: experimental + !> + !> Returns an instance of type 'stringlist_index_type' representing backward index + !> [Specifications](../page/specs/stdlib_stringlist.html#bidx) interface bidx module procedure backward_index end interface @@ -60,20 +68,38 @@ module stdlib_stringlist contains private + procedure :: copy => create_copy + procedure, public :: destroy => destroy_list + + procedure, public :: len => length_list + + procedure :: capacity => capacity_list + + procedure :: to_idxn => convert_to_idxn + + procedure :: insert_char_idx => insert_char_idx_wrap procedure :: insert_string_idx => insert_string_idx_wrap - procedure :: insert_string_int => insert_string_int_impl procedure :: insert_stringlist_idx => insert_stringlist_idx_wrap - procedure :: insert_stringlist_int => insert_stringlist_int_impl + procedure :: insert_chararray_idx => insert_chararray_idx_wrap procedure :: insert_stringarray_idx => insert_stringarray_idx_wrap + generic, public :: insert => insert_char_idx, & + insert_string_idx, & + insert_stringlist_idx, & + insert_chararray_idx, & + insert_stringarray_idx + + procedure :: insert_string_int => insert_string_int_impl + procedure :: insert_stringlist_int => insert_stringlist_int_impl + procedure :: insert_chararray_int => insert_chararray_int_impl procedure :: insert_stringarray_int => insert_stringarray_int_impl - generic, public :: insert => insert_string_int, insert_string_idx, & - insert_stringlist_int, insert_stringlist_idx, & - insert_stringarray_int, insert_stringarray_idx - procedure :: get_string_int => get_string_int_impl + + ! procedure :: get_string_int => get_string_int_impl procedure :: get_string_idx => get_string_idx_wrap - generic, public :: get => get_string_int, get_string_idx - procedure, public :: len => length_list + generic, public :: get => get_string_idx + ! get_string_int + + ! procedure, public :: sort => sort_list ! procedure, public :: index => index_of_string, index_of_char ! procedure, public :: index_sub => index_of_substring, index_of_subchar @@ -115,6 +141,11 @@ module stdlib_stringlist end type stringlist_type + !> Version: experimental + !> + !> Concatenates stringlist with the input entity + !> Returns a new stringlist + !> [Specifications](../page/specs/stdlib_stringlist.html#append-operator) interface operator(//) module procedure append_char module procedure append_string @@ -164,357 +195,438 @@ module stdlib_stringlist ! end function stringlist_index_subtract -pure function forward_index(idx) - integer, intent(in) :: idx - type(stringlist_index_type) :: forward_index + !> Returns an instance of type 'stringlist_index_type' representing forward index 'idx' + pure function forward_index(idx) + integer, intent(in) :: idx + type(stringlist_index_type) :: forward_index - forward_index = stringlist_index_type( .true., idx ) + forward_index = stringlist_index_type( .true., idx ) -end function forward_index + end function forward_index -pure function backward_index(idx) - integer, intent(in) :: idx - type(stringlist_index_type) :: backward_index + !> Returns an instance of type 'stringlist_index_type' representing backward index 'idx' + pure function backward_index(idx) + integer, intent(in) :: idx + type(stringlist_index_type) :: backward_index - backward_index = stringlist_index_type( .false., idx ) + backward_index = stringlist_index_type( .false., idx ) -end function backward_index + end function backward_index -pure function append_char( list, string ) - type(stringlist_type), intent(in) :: list - character(len=*), intent(in) :: string - type(stringlist_type) :: append_char + pure function create_copy( original ) + class(stringlist_type), intent(in) :: original + type(stringlist_type) :: create_copy - append_char = list // string_type( string ) + create_copy = original -end function append_char + end function create_copy -pure function append_string( list, string ) - type(stringlist_type), intent(in) :: list - type(string_type), intent(in) :: string - type(stringlist_type) :: append_string + !> Appends character scalar 'string' to the stringlist 'list' + !> Returns a new stringlist + function append_char( list, string ) + type(stringlist_type), intent(in) :: list + character(len=*), intent(in) :: string + type(stringlist_type) :: append_char - append_string = list - call append_string%insert( list_tail, string ) + append_char = list // string_type( string ) -end function append_string + end function append_char -pure function prepend_char( string, list ) - character(len=*), intent(in) :: string - type(stringlist_type), intent(in) :: list - type(stringlist_type) :: prepend_char + !> Appends string 'string' to the stringlist 'list' + !> Returns a new stringlist + function append_string( list, string ) + type(stringlist_type), intent(in) :: list + type(string_type), intent(in) :: string + type(stringlist_type) :: append_string - prepend_char = string_type( string ) // list + append_string = list%copy() + call append_string%insert( list_tail, string ) -end function prepend_char + end function append_string -pure function prepend_string( string, list ) - type(string_type), intent(in) :: string - type(stringlist_type), intent(in) :: list - type(stringlist_type) :: prepend_string + !> Prepends character scalar 'string' to the stringlist 'list' + !> Returns a new stringlist + function prepend_char( string, list ) + character(len=*), intent(in) :: string + type(stringlist_type), intent(in) :: list + type(stringlist_type) :: prepend_char - prepend_string = list - call prepend_string%insert( list_head, string ) + prepend_char = string_type( string ) // list -end function prepend_string + end function prepend_char -pure function append_stringlist( list, slist ) - type(stringlist_type), intent(in) :: list - type(stringlist_type), intent(in) :: slist - type(stringlist_type) :: append_stringlist + !> Prepends string 'string' to the stringlist 'list' + !> Returns a new stringlist + function prepend_string( string, list ) + type(string_type), intent(in) :: string + type(stringlist_type), intent(in) :: list + type(stringlist_type) :: prepend_string - append_stringlist = list - call append_stringlist%insert( list_tail, slist ) + prepend_string = list%copy() + call prepend_string%insert( list_head, string ) -end function append_stringlist + end function prepend_string -pure function append_stringarray( list, sarray ) - type(stringlist_type), intent(in) :: list - character(len=*), dimension(:), intent(in) :: sarray - type(stringlist_type) :: append_stringarray + !> Appends stringlist 'slist' to the stringlist 'list' + !> Returns a new stringlist + function append_stringlist( list, slist ) + type(stringlist_type), intent(in) :: list + type(stringlist_type), intent(in) :: slist + type(stringlist_type) :: append_stringlist - append_stringarray = list - call append_stringarray%insert( list_tail, sarray ) + append_stringlist = list%copy() + call append_stringlist%insert( list_tail, slist ) -end function append_stringarray + end function append_stringlist -pure function prepend_stringarray( sarray, list ) - character(len=*), dimension(:), intent(in) :: sarray - type(stringlist_type), intent(in) :: list - type(stringlist_type) :: prepend_stringarray + !> Appends stringarray 'sarray' to the stringlist 'list' + !> Returns a new stringlist + function append_stringarray( list, sarray ) + type(stringlist_type), intent(in) :: list + character(len=*), dimension(:), intent(in) :: sarray + type(stringlist_type) :: append_stringarray - prepend_stringarray = list - call prepend_stringarray%insert( list_head, sarray ) + append_stringarray = list%copy() + call append_stringarray%insert( list_tail, sarray ) -end function prepend_stringarray + end function append_stringarray + !> Prepends stringarray 'sarray' to the stringlist 'list' + !> Returns a new stringlist + function prepend_stringarray( sarray, list ) + character(len=*), dimension(:), intent(in) :: sarray + type(stringlist_type), intent(in) :: list + type(stringlist_type) :: prepend_stringarray -! destroy_list -- -! Destroy the contents of the list -! -! Arguments: -! list The list of strings in question -! -subroutine destroy_list( list ) - type(stringlist_type), intent(out) :: list + prepend_stringarray = list%copy() + call prepend_stringarray%insert( list_head, sarray ) - list%size = 0 - deallocate( list%stringarray ) - -end subroutine destroy_list - -! length_list -- -! Return the size (length) of the list -! -! Arguments: -! list The list of strings to retrieve the string from -! -pure integer function length_list( list ) - type(stringlist_type), intent(in) :: list - - length_list = list%size - -end function length_list - -pure integer function capacity( list ) - type(stringlist_type), intent(in) :: list - - capacity = 0 - if ( allocated( list%stringarray ) ) then - capacity = size( list%stringarray ) - end if - -end function capacity - -! Convert fidx and bidx to the equivalent integer -pure integer function to_idxn( idx ) - type(stringlist_index_type), intent(in) :: idx - integer :: to_idxn - - to_idxn = merge( idx%offset, list%size + 2 - idx%offset, idx%head ) - -end function to_idxn - -! insert_string -- -! Insert a new string (or an array of strings of another list) into the list -! -! Arguments: -! list The list of strings where the new string(s) should be inserted -! idx Index at which to insert the string -! string The string in question -! -subroutine insert_char_idx_wrap( list, idx, string ) - type(stringlist_type), intent(inout) :: list - type(stringlist_index_type), intent(in) :: idx - character(len=*), intent(in) :: string + end function prepend_stringarray - call list%insert( idx, string_type( string ) ) + ! destroy: -end subroutine insert_char_idx_wrap + !> Version: experimental + !> + !> Resets stringlist 'list' to an empy stringlist of len 0 + !> Modifies the input stringlist 'list' + subroutine destroy_list( list ) + !> TODO: needs a better name?? like clear_list or reset_list + class(stringlist_type), intent(out) :: list -subroutine insert_string_idx_wrap( list, idx, string ) - type(stringlist_type), intent(inout) :: list - type(stringlist_index_type), intent(in) :: idx - type(string_type), intent(in) :: string + list%size = 0 + deallocate( list%stringarray ) - call list%insert( to_idxn( idx ), string ) + end subroutine destroy_list -end subroutine insert_string_idx_wrap + ! len: -subroutine insert_stringlist_idx_wrap( list, idx, slist ) - type(stringlist_type), intent(inout) :: list - type(stringlist_index_type), intent(in) :: idx - type(stringlist_type), intent(in) :: slist + !> Version: experimental + !> + !> Returns the len (length) of the list + !> Returns an integer + pure integer function length_list( list ) + class(stringlist_type), intent(in) :: list - call list%insert( to_idxn( idx ), slist ) + length_list = list%size -end subroutine insert_stringlist_idx_wrap + end function length_list -subroutine insert_stringarray_idx_wrap( list, idx, sarray ) - type(stringlist_type), intent(inout) :: list - type(stringlist_index_type), intent(in) :: idx - character(len=*), dimension(:), intent(in) :: sarray + ! capacity: - call list%insert( to_idxn( idx ), sarray ) + !> Version: experimental + !> + !> Returns the capacity of the list + !> Returns an integer + pure integer function capacity_list( list ) + !> Not a part of public API + class(stringlist_type), intent(in) :: list -end subroutine insert_stringarray_idx_wrap - -! insert_empty_positions -! Insert a number of positions for new strings -! -! Arguments: -! list The list of strings where the empty positions should be inserted -! idxn Index at which the positions should be inserted -! number Number of positions -! -subroutine insert_empty_positions( list, idxn, number ) - type(stringlist_type), intent(inout) :: list - integer, intent(inout) :: idxn - integer, intent(inout) :: number - - integer :: i, inew - integer :: new_size, old_size - type(string_type), dimension(:), allocatable :: new_stringarray - - if (number > 0) then - - idxn = clip( idxn, 1, len(list) + 1 ) - old_size = len(list) - new_size = old_size + number - - if ( capacity(list) < new_size ) then - - allocate( new_stringarray(new_size) ) - - do i = 1, idxn - 1 - call move( list%stringarray(i), new_stringarray(i) ) - end do - do i = idxn, old_size - inew = i + number - call move( list%stringarray(i), new_stringarray(inew) ) - end do - - call move_alloc( new_stringarray, list%stringarray ) - - else - do i = old_size, idxn, -1 - inew = i + number - call move( list%stringarray(i), list%stringarray(inew) ) - end do + capacity_list = 0 + if ( allocated( list%stringarray ) ) then + capacity_list = size( list%stringarray ) end if - list%size = new_size + end function capacity_list - else - number = 0 - end if - -end subroutine insert_empty_positions - -! insert_char_int_impl -- -! Insert a new string into the list - specific implementation -! -subroutine insert_char_int_impl( list, idx, string ) - type(stringlist_type), intent(inout) :: list - integer, intent(in) :: idx - character(len=*), intent(in) :: string + ! to_idxn: - call insert( list, idx, string_type( string ) ) + !> Version: experimental + !> + !> Converts a forward index or backward index to its equivalent integer index + !> Returns an integer + pure integer function convert_to_idxn( list, idx ) + !> Not a part of public API + class(stringlist_type), intent(in) :: list + type(stringlist_index_type), intent(in) :: idx -end subroutine insert_char_int_impl + convert_to_idxn = merge( idx%offset, list%len() + 2 - idx%offset, idx%forward ) + + end function convert_to_idxn + + ! insert: + + !> Version: experimental + !> + !> Inserts character scalar 'string' at stringlist_index 'idx' in stringlist 'list' + !> Modifies the input stringlist 'list' + subroutine insert_char_idx_wrap( list, idx, string ) + class(stringlist_type), intent(inout) :: list + type(stringlist_index_type), intent(in) :: idx + character(len=*), intent(in) :: string + + call list%insert( idx, string_type( string ) ) -! insert_string_int_impl -- -! Insert a new string into the list - specific implementation -! -subroutine insert_string_int_impl( list, idx, string ) - type(stringlist_type), intent(inout) :: list - integer, intent(in) :: idx - type(string_type), intent(in) :: string + end subroutine insert_char_idx_wrap - integer :: idxn + !> Version: experimental + !> + !> Inserts string 'string' at stringlist_index 'idx' in stringlist 'list' + !> Modifies the input stringlist 'list' + subroutine insert_string_idx_wrap( list, idx, string ) + class(stringlist_type), intent(inout) :: list + type(stringlist_index_type), intent(in) :: idx + type(string_type), intent(in) :: string - idxn = idx - call insert_empty_positions( list, idxn, 1 ) + call list%insert_string_int( list%to_idxn( idx ), string ) - list%stringarray(idxn) = string + end subroutine insert_string_idx_wrap -end subroutine insert_string_int_impl + !> Version: experimental + !> + !> Inserts stringlist 'slist' at stringlist_index 'idx' in stringlist 'list' + !> Modifies the input stringlist 'list' + subroutine insert_stringlist_idx_wrap( list, idx, slist ) + class(stringlist_type), intent(inout) :: list + type(stringlist_index_type), intent(in) :: idx + type(stringlist_type), intent(in) :: slist -! insert_stringlist_int_impl -- -! Insert a list of strings into the list - specific implementation -! -subroutine insert_stringlist_int_impl( list, idx, slist ) - type(stringlist_type), intent(inout) :: list - integer, intent(in) :: idx - type(stringlist_type), intent(in) :: slist + call list%insert_stringlist_int( list%to_idxn( idx ), slist ) - integer :: i - integer :: idxn, idxnew + end subroutine insert_stringlist_idx_wrap - idxn = idx - call insert_empty_positions( list, idxn, len( slist ) ) + !> Version: experimental + !> + !> Inserts chararray 'carray' at stringlist_index 'idx' in stringlist 'list' + !> Modifies the input stringlist 'list' + subroutine insert_chararray_idx_wrap( list, idx, carray ) + class(stringlist_type), intent(inout) :: list + type(stringlist_index_type), intent(in) :: idx + character(len=*), dimension(:), intent(in) :: carray - do i = 1, len( slist ) - idxnew = idxn + i - 1 - list%stringarray(idxnew) = slist%stringarray(i) - end do + call list%insert_chararray_int( list%to_idxn( idx ), carray ) -end subroutine insert_stringlist_int_impl + end subroutine insert_chararray_idx_wrap -! insert_chararray_int_impl -- -! Insert an array of chars into the list - specific implementatinon -! -subroutine insert_chararray_int_impl( list, idx, sarray ) - type(stringlist_type), intent(inout) :: list - integer, intent(in) :: idx - character(len=*), dimension(:), intent(in) :: sarray + !> Version: experimental + !> + !> Inserts stringarray 'sarray' at stringlist_index 'idx' in stringlist 'list' + !> Modifies the input stringlist 'list' + subroutine insert_stringarray_idx_wrap( list, idx, sarray ) + class(stringlist_type), intent(inout) :: list + type(stringlist_index_type), intent(in) :: idx + type(string_type), dimension(:), intent(in) :: sarray - integer :: i - integer :: idxn, idxnew + call list%insert_stringarray_int( list%to_idxn( idx ), sarray ) - idxn = idx - call insert_empty_positions( list, idxn, size( sarray ) ) + end subroutine insert_stringarray_idx_wrap - do i = 1, size( sarray ) - idxnew = idxn + i - 1 - list%stringarray(idxnew) = string_type( sarray(i) ) - end do + !> Version: experimental + !> + !> Inserts 'positions' number of empty positions at integer index 'idxn' + !> Modifies the input stringlist 'list' + subroutine insert_empty_positions( list, idxn, positions ) + !> Not a part of public API + class(stringlist_type), intent(inout) :: list + integer, intent(inout) :: idxn + integer, intent(inout) :: positions -end subroutine insert_chararray_int_impl + integer :: i, inew + integer :: new_len, old_len + type(string_type), dimension(:), allocatable :: new_stringarray -! insert_stringarray_int_impl -- -! Insert an array of strings into the list - specific implementatinon -! -subroutine insert_stringarray_int_impl( list, idx, sarray ) - type(stringlist_type), intent(inout) :: list - integer, intent(in) :: idx - type(string_type), dimension(:), intent(in) :: sarray + if (positions > 0) then - integer :: i - integer :: idxn, idxnew + idxn = clip( idxn, 1, list%len() + 1 ) + old_len = list%len() + new_len = old_len + positions + + if ( list%capacity() < new_len ) then + + allocate( new_stringarray(new_len) ) + + do i = 1, idxn - 1 + ! TODO: can be improved by move + new_stringarray(i) = list%stringarray(i) + end do + do i = idxn, old_len + inew = i + positions + ! TODO: can be improved by move + new_stringarray(inew) = list%stringarray(i) + end do + + call move_alloc( new_stringarray, list%stringarray ) + + else + do i = old_len, idxn, -1 + inew = i + positions + ! TODO: can be improved by move + list%stringarray(inew) = list%stringarray(i) + end do + end if - idxn = idx - call insert_empty_positions( list, idxn, size( sarray ) ) + list%size = new_len - do i = 1, size( sarray ) - idxnew = idxn + i - 1 - list%stringarray(idxnew) = sarray(i) - end do + else + positions = 0 + end if -end subroutine insert_stringarray_int_impl + end subroutine insert_empty_positions -! get_string -- -! Get the string at a particular index -! -! Arguments: -! list The list of strings to retrieve the string from -! idx Index after which to insert the string +! insert_char_int_impl -- +! Insert a new string into the list - specific implementation ! -pure function get_string_idx_wrap( list, idx ) - type(stringlist_type), intent(in) :: list - type(stringlist_index_type), intent(in) :: idx - type(string_type) :: get_string_idx_wrap - - get_string_idx_wrap = list%get( to_idxn(idx) ) +! subroutine insert_char_int_impl( list, idx, string ) +! type(stringlist_type), intent(inout) :: list +! integer, intent(in) :: idx +! character(len=*), intent(in) :: string + +! call insert( list, idx, string_type( string ) ) + +! end subroutine insert_char_int_impl + + !> Version: experimental + !> + !> Inserts string 'string' at integer index 'idxn' in stringlist 'list' + !> Modifies the input stringlist 'list' + subroutine insert_string_int_impl( list, idxn, string ) + !> Not a part of public API + class(stringlist_type), intent(inout) :: list + integer, intent(in) :: idxn + type(string_type), intent(in) :: string + + integer :: work_idxn + integer :: positions + + work_idxn = idxn + positions = 1 + call insert_empty_positions( list, work_idxn, positions ) + + list%stringarray(work_idxn) = string + + end subroutine insert_string_int_impl + + !> Version: experimental + !> + !> Inserts stringlist 'slist' at integer index 'idxn' in stringlist 'list' + !> Modifies the input stringlist 'list' + subroutine insert_stringlist_int_impl( list, idxn, slist ) + !> Not a part of public API + class(stringlist_type), intent(inout) :: list + integer, intent(in) :: idxn + type(stringlist_type), intent(in) :: slist + + integer :: i + integer :: work_idxn, idxnew + integer :: positions + + work_idxn = idxn + positions = slist%len() + call insert_empty_positions( list, work_idxn, positions ) + + do i = 1, slist%len() + idxnew = work_idxn + i - 1 + list%stringarray(idxnew) = slist%stringarray(i) + end do + + end subroutine insert_stringlist_int_impl + + !> Version: experimental + !> + !> Inserts chararray 'carray' at integer index 'idxn' in stringlist 'list' + !> Modifies the input stringlist 'list' + subroutine insert_chararray_int_impl( list, idxn, carray ) + !> Not a part of public API + class(stringlist_type), intent(inout) :: list + integer, intent(in) :: idxn + character(len=*), dimension(:), intent(in) :: carray + + integer :: i + integer :: work_idxn, idxnew + integer :: positions + + work_idxn = idxn + positions = size( carray ) + call insert_empty_positions( list, work_idxn, positions ) + + do i = 1, size( carray ) + idxnew = work_idxn + i - 1 + list%stringarray(idxnew) = string_type( carray(i) ) + end do + + end subroutine insert_chararray_int_impl + + !> Version: experimental + !> + !> Inserts stringarray 'sarray' at integer index 'idxn' in stringlist 'list' + !> Modifies the input stringlist 'list' + subroutine insert_stringarray_int_impl( list, idxn, sarray ) + !> Not a part of public API + class(stringlist_type), intent(inout) :: list + integer, intent(in) :: idxn + type(string_type), dimension(:), intent(in) :: sarray + + integer :: i + integer :: work_idxn, idxnew + integer :: positions + + work_idxn = idxn + positions = size( sarray ) + call insert_empty_positions( list, work_idxn, positions ) + + do i = 1, size( sarray ) + idxnew = work_idxn + i - 1 + list%stringarray(idxnew) = sarray(i) + end do + + end subroutine insert_stringarray_int_impl + + ! get: + + !> Version: experimental + !> + !> Returns the string present at stringlist_index 'idx' in stringlist 'list' + !> Returns string_type instance + pure function get_string_idx_wrap( list, idx ) + class(stringlist_type), intent(in) :: list + type(stringlist_index_type), intent(in) :: idx + type(string_type) :: get_string_idx_wrap + + integer :: idxn + + idxn = list%to_idxn( idx ) + + ! - if the index is out of bounds, return a string_type equivalent to empty string + if ( 1 <= idxn .and. idxn <= list%len() ) then + get_string_idx_wrap = list%stringarray(idxn) -end function get_string_idx_wrap + end if -pure function get_string_int_impl( list, idxn ) - type(stringlist_type), intent(in) :: list - integer, intent(in) :: idxn - type(string_type) :: get_string_int_impl + end function get_string_idx_wrap - integer :: idxnew +! pure function get_string_int_impl( list, idxn ) +! class(stringlist_type), intent(in) :: list +! integer, intent(in) :: idxn +! type(string_type) :: get_string_int_impl - ! - ! Examine the actual index: - ! - if the index is out of bounds, return a string_type equivalent to empty string - ! - if ( 1 <= idxn .and. idxn <= len( list ) ) then - get_string_int_impl = list%stringarray(idx) - end if +! ! +! ! Examine the actual index: +! ! - if the index is out of bounds, return a string_type equivalent to empty string +! ! +! if ( 1 <= idxn .and. idxn <= list%len() ) then +! get_string_int_impl = list%stringarray(idxn) +! end if -end function get_string_int_impl +! end function get_string_int_impl ! ! sort_list -- ! ! Sort the list and return the result as a new list From 0128f4eb301b26ffabdc60a73a970e525d32327c Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Thu, 29 Jul 2021 00:29:47 +0530 Subject: [PATCH 09/40] cleaned PR and saved comments in another branch --- src/stdlib_stringlist.f90 | 647 +------------------------------------- 1 file changed, 1 insertion(+), 646 deletions(-) diff --git a/src/stdlib_stringlist.f90 b/src/stdlib_stringlist.f90 index 622f92c52..4af056d1e 100644 --- a/src/stdlib_stringlist.f90 +++ b/src/stdlib_stringlist.f90 @@ -23,7 +23,7 @@ module stdlib_stringlist private public :: stringlist_type, operator(//) - public :: list_head, list_tail, fidx, bidx, stringlist_index_type !, operator(+), operator(-) + public :: list_head, list_tail, fidx, bidx, stringlist_index_type type stringlist_index_type private @@ -34,16 +34,6 @@ module stdlib_stringlist type(stringlist_index_type), parameter :: list_head = stringlist_index_type( .true. , 1 ) ! fidx(1) type(stringlist_index_type), parameter :: list_tail = stringlist_index_type( .false., 1 ) ! bidx(1) - ! type(stringlist_index_type), parameter :: list_end = stringlist_index_type( .false., 0 ) - ! type(stringlist_index_type), parameter :: list_after_end = stringlist_index_type( .false., 1 ) - - ! interface operator(+) - ! module procedure stringlist_index_add - ! end interface - - ! interface operator(-) - ! module procedure stringlist_index_subtract - ! end interface !> Version: experimental !> @@ -99,46 +89,6 @@ module stdlib_stringlist generic, public :: get => get_string_idx ! get_string_int - - ! procedure, public :: sort => sort_list - ! procedure, public :: index => index_of_string, index_of_char - ! procedure, public :: index_sub => index_of_substring, index_of_subchar - ! procedure :: delete_strings_int_int => delete_strings_int_int_impl - ! procedure :: delete_strings_idx_int => delete_strings_idx_int_wrap - ! procedure :: delete_strings_int_idx => delete_strings_int_idx_wrap - ! procedure :: delete_strings_idx_idx => delete_strings_idx_idx_wrap - ! generic, public :: delete => delete_strings_int_int, delete_strings_idx_int, & - ! delete_strings_int_idx, delete_strings_idx_idx - ! procedure :: range_list_int_int => range_list_int_int_impl - ! procedure :: range_list_idx_int => range_list_idx_int_wrap - ! procedure :: range_list_int_idx => range_list_int_idx_wrap - ! procedure :: range_list_idx_idx => range_list_idx_idx_wrap - ! generic, public :: range => range_list_int_int, range_list_idx_idx, & - ! range_list_int_idx, range_list_idx_int - ! procedure :: replace_string_idx => replace_string_idx_wrap - ! procedure :: replace_string_int => replace_string_int_impl - ! procedure :: replace_string_int_int => replace_string_int_int_impl - ! procedure :: replace_stringarray_int_int => replace_stringarray_int_int_impl - ! procedure :: replace_stringlist_int_int => replace_stringlist_int_int_impl - ! procedure :: replace_string_idx_idx => replace_string_idx_idx_wrap - ! procedure :: replace_stringarray_idx_idx => replace_stringarray_idx_idx_wrap - ! procedure :: replace_stringlist_idx_idx => replace_stringlist_idx_idx_wrap - ! procedure :: replace_string_idx_int => replace_string_idx_int_wrap - ! procedure :: replace_stringarray_idx_int => replace_stringarray_idx_int_wrap - ! procedure :: replace_stringlist_idx_int => replace_stringlist_idx_int_wrap - ! procedure :: replace_string_int_idx => replace_string_int_idx_wrap - ! procedure :: replace_stringarray_int_idx => replace_stringarray_int_idx_wrap - ! procedure :: replace_stringlist_int_idx => replace_stringlist_int_idx_wrap - ! generic, public :: replace => replace_string_int_int, replace_stringarray_int_int, & - ! replace_stringlist_int_int, & - ! replace_string_idx, replace_string_int, & - ! replace_string_idx_idx, replace_stringarray_idx_idx, & - ! replace_stringlist_idx_idx, & - ! replace_string_idx_int, replace_stringarray_idx_int, & - ! replace_stringlist_idx_int, & - ! replace_string_int_idx, replace_stringarray_int_idx, & - ! replace_stringlist_int_idx - end type stringlist_type !> Version: experimental @@ -158,43 +108,6 @@ module stdlib_stringlist contains - -! stringlist_index_add -- -! Add an integer offset to the special index -! -! Arguments: -! index Special index -! offset Offset to be added -! -! function stringlist_index_add( index, offset ) -! type(stringlist_index_type), intent(in) :: index -! integer, intent(in) :: offset - -! type(stringlist_index_type) :: stringlist_index_add - -! stringlist_index_add = index -! stringlist_index_add%offset = stringlist_index_add%offset + offset - -! end function stringlist_index_add - -! stringlist_index_subtract -- -! Subtract an integer offset to the special index -! -! Arguments: -! index Special index -! offset Offset to be subtracted -! -! function stringlist_index_subtract( index, offset ) -! type(stringlist_index_type), intent(in) :: index -! integer, intent(in) :: offset - -! type(stringlist_index_type) :: stringlist_index_subtract - -! stringlist_index_subtract = index -! stringlist_index_subtract%offset = stringlist_index_subtract%offset - offset - -! end function stringlist_index_subtract - !> Returns an instance of type 'stringlist_index_type' representing forward index 'idx' pure function forward_index(idx) integer, intent(in) :: idx @@ -613,563 +526,5 @@ pure function get_string_idx_wrap( list, idx ) end function get_string_idx_wrap -! pure function get_string_int_impl( list, idxn ) -! class(stringlist_type), intent(in) :: list -! integer, intent(in) :: idxn -! type(string_type) :: get_string_int_impl - -! ! -! ! Examine the actual index: -! ! - if the index is out of bounds, return a string_type equivalent to empty string -! ! -! if ( 1 <= idxn .and. idxn <= list%len() ) then -! get_string_int_impl = list%stringarray(idxn) -! end if - -! end function get_string_int_impl - -! ! sort_list -- -! ! Sort the list and return the result as a new list -! ! -! ! Arguments: -! ! list The list of strings to retrieve the string from -! ! ascending Whether to sort as ascending (true) or not (false) -! ! -! function sort_list( list, ascending ) -! class(stringlist_type), intent(in) :: list -! logical, intent(in), optional :: ascending - -! integer :: i -! integer, dimension(:), allocatable :: idx -! class(stringlist_type), allocatable :: sort_list -! logical :: ascending_order - -! ! -! ! Allocate and fill the index array, then sort the indices -! ! based on the strings -! ! -! idx = [ (i ,i=1,list%size) ] - -! ascending_order = .true. -! if ( present(ascending) ) then -! ascending_order = ascending -! endif - -! if ( ascending_order ) then -! idx = sort_ascending( idx ) -! else -! idx = sort_descending( idx ) -! endif - -! allocate( sort_list ) -! allocate( sort_list%string(list%size) ) - -! do i = 1,list%size -! sort_list%string(i) = list%string(idx(i)) -! enddo -! sort_list%size = list%size - -! contains -! recursive function sort_ascending( idx ) result(idxnew) -! integer, dimension(:) :: idx -! integer, dimension(size(idx)) :: idxnew - -! if ( size(idx) > 1 ) then -! idxnew = [ sort_ascending( pack( idx, list%string(idx) < list%string(idx(1)) ) ), & -! pack( idx, list%string(idx) == list%string(idx(1)) ) , & -! sort_ascending( pack( idx, list%string(idx) > list%string(idx(1)) ) ) ] -! else -! idxnew = idx -! endif -! end function sort_ascending - -! recursive function sort_descending( idx ) result(idxnew) -! integer, dimension(:) :: idx -! integer, dimension(size(idx)) :: idxnew - -! if ( size(idx) > 1 ) then -! idxnew = [ sort_descending( pack( idx, list%string(idx) > list%string(idx(1)) ) ), & -! pack( idx, list%string(idx) == list%string(idx(1)) ) , & -! sort_descending( pack( idx, list%string(idx) < list%string(idx(1)) ) ) ] -! else -! idxnew = idx -! endif -! end function sort_descending - -! end function sort_list - -! ! index_of_char -- -! ! Return the index in the list of a particular string -! ! -! ! Arguments: -! ! list The list of strings in which to search the string -! ! string The string to be found -! ! back Whether to search from the end (true) or not (false, default) -! ! -! integer function index_of_char( list, string, back ) -! class(stringlist_type), intent(in) :: list -! character(len=*), intent(in) :: string -! logical, intent(in), optional :: back - -! integer :: idx -! integer :: i, first, last, stride - -! if ( optval(back, .false.) ) then -! first = list%size -! last = 1 -! stride = -1 -! else -! first = 1 -! last = list%size -! stride = 1 -! end if - -! idx = 0 -! do i = first, last, stride -! if ( list%stringarray(i) == string ) then -! idx = i -! exit -! end if -! end do - -! index_of_string = idx - -! end function index_of_char - -! integer function index_of_string( list, string, back ) -! class(stringlist_type), intent(in) :: list -! type(string_type), intent(in) :: string -! logical, intent(in), optional :: back - -! index_of_string = index_of_char(list, char(string), back) - -! end function index_of_string - -! ! index_of_substring -- -! ! Return the index in the list of a string containing a particular substring -! ! -! ! Arguments: -! ! list The list of strings in which to search the string -! ! substring The substring to be found -! ! back Whether to search from the end (true) or not (false, default) -! ! -! integer function index_of_subchar( list, substring, back ) -! class(stringlist_type), intent(in) :: list -! character(len=*), intent(in) :: substring -! logical, intent(in), optional :: back - -! integer :: idx -! integer :: i, first, last, stride - -! if ( optval(back, .false.) ) then -! first = list%size -! last = 1 -! stride = -1 -! else -! first = 1 -! last = list%size -! stride = 1 -! end if - -! idx = 0 -! do i = first, last, stride -! if ( find( list%stringarray(i), substring ) > 0 ) then -! idx = i -! exit -! end if -! end do - -! index_of_substring = idx - -! end function index_of_subchar - -! integer function index_of_substring( list, string, back ) -! class(stringlist_type), intent(in) :: list -! type(string_type), intent(in) :: string -! logical, intent(in), optional :: back - -! index_of_substring = index_of_subchar(list, char(string), back) - -! end function index_of_substring - -! ! delete_strings -- -! ! Delete one or more strings from the list -! ! -! ! Arguments: -! ! list The list of strings in which to search the string -! ! first The position of the first string to be deleted -! ! last The position of the last string to be deleted -! ! -! ! Note: -! ! If the range defined by first and last has a zero length or first > last, -! ! then nothing happens. -! ! -! subroutine delete_strings_idx_idx_wrap( list, first, last ) -! class(stringlist_type), intent(inout) :: list -! type(stringlist_index_type), intent(in) :: first -! type(stringlist_index_type), intent(in) :: last - -! integer :: firstpos -! integer :: lastpos - -! firstpos = merge( first%offset, list%size + first%offset, first%head ) -! lastpos = merge( last%offset, list%size + last%offset, last%head ) - -! call list%delete( firstpos, lastpos ) -! end subroutine delete_strings_idx_idx_wrap - -! subroutine delete_strings_int_idx_wrap( list, first, last ) -! class(stringlist_type), intent(inout) :: list -! integer, intent(in) :: first -! type(stringlist_index_type), intent(in) :: last - -! integer :: firstpos -! integer :: lastpos - -! lastpos = merge( last%offset, list%size + last%offset, last%head ) - -! call list%delete( firstpos, lastpos ) -! end subroutine delete_strings_int_idx_wrap - -! subroutine delete_strings_idx_int_wrap( list, first, last ) -! class(stringlist_type), intent(inout) :: list -! type(stringlist_index_type), intent(in) :: first -! integer, intent(in) :: last - -! integer :: firstpos -! integer :: lastpos - -! firstpos = merge( first%offset, list%size + first%offset, first%head ) - -! call list%delete( firstpos, lastpos ) -! end subroutine delete_strings_idx_int_wrap - -! subroutine delete_strings_int_int_impl( list, first, last ) -! class(stringlist_type), intent(inout) :: list -! integer, intent(in) :: first -! integer, intent(in) :: last - -! integer :: firstpos -! integer :: lastpos -! integer :: i -! integer :: j - -! if ( first > list%size .or. last < 1 ) then -! return -! endif - -! firstpos = max( 1, min(list%size, first ) ) -! lastpos = max( 1, min(list%size, last ) ) - -! if ( firstpos > lastpos ) then -! return -! else -! do i = lastpos+1,list%size -! j = firstpos + i - lastpos - 1 -! call move_alloc( list%string(i)%value, list%string(j)%value ) -! enddo -! do i = list%size - (lastpos-firstpos), list%size -! list%string(i)%value = '' -! enddo - -! list%size = list%size - (lastpos-firstpos + 1) -! endif -! end subroutine delete_strings_int_int_impl - -! ! range_list -- -! ! Return a sublist given by the first and last position -! ! -! ! Arguments: -! ! list The list of strings in which to search the string -! ! first The position of the first string to be deleted -! ! last The position of the last string to be deleted -! ! -! ! Note: -! ! If the range defined by first and last has a zero length or first > last, -! ! then return an empty list -! ! -! function range_list_idx_idx_wrap( list, first, last ) -! class(stringlist_type), intent(inout) :: list -! type(stringlist_index_type), intent(in) :: first -! type(stringlist_index_type), intent(in) :: last -! class(stringlist_type), allocatable :: range_list_idx_idx_wrap - -! integer :: firstpos -! integer :: lastpos - -! firstpos = merge( first%offset, list%size + first%offset, first%head ) -! lastpos = merge( last%offset, list%size + last%offset, last%head ) - -! range_list_idx_idx_wrap = list%range( firstpos, lastpos ) - -! end function range_list_idx_idx_wrap - -! function range_list_int_idx_wrap( list, first, last ) -! class(stringlist_type), intent(inout) :: list -! integer, intent(in) :: first -! type(stringlist_index_type), intent(in) :: last -! class(stringlist_type), allocatable :: range_list_int_idx_wrap - -! integer :: lastpos - -! lastpos = merge( last%offset, list%size + last%offset, last%head ) - -! range_list_int_idx_wrap = list%range( first, lastpos ) - -! end function range_list_int_idx_wrap - -! function range_list_idx_int_wrap( list, first, last ) -! class(stringlist_type), intent(inout) :: list -! type(stringlist_index_type), intent(in) :: first -! integer, intent(in) :: last -! class(stringlist_type), allocatable :: range_list_idx_int_wrap - -! integer :: firstpos - -! firstpos = merge( first%offset, list%size + first%offset, first%head ) - -! range_list_idx_int_wrap = list%range( firstpos, last ) - -! end function range_list_idx_int_wrap - -! function range_list_int_int_impl( list, first, last ) -! class(stringlist_type), intent(inout) :: list -! integer, intent(in) :: first -! integer, intent(in) :: last -! class(stringlist_type), allocatable :: range_list_int_int_impl - -! integer :: firstpos -! integer :: lastpos - -! allocate( range_list_int_int_impl ) - -! if ( first > list%size .or. last < 1 ) then -! allocate( range_list_int_int_impl%string(0) ) -! return -! endif - -! firstpos = max( 1, min(list%size, first ) ) -! lastpos = max( 1, min(list%size, last ) ) - -! if ( firstpos > lastpos ) then -! allocate( range_list_int_int_impl%string(0) ) -! return -! else -! range_list_int_int_impl%size = lastpos - firstpos + 1 -! range_list_int_int_impl%string = list%string(firstpos:lastpos) -! endif -! end function range_list_int_int_impl - - -! ! replace_string -- -! ! Replace a string in the list -! ! -! ! Arguments: -! ! list The list of strings in which to replace a string (or a range of strings) -! ! first First index of the string(s) to be replaced -! ! last Last index of the string(s) to be replaced -! ! string The string in question (array of strings or another string list) -! ! -! ! Note: -! ! For convenience a version that simply replaces a single string is provided -! ! -! subroutine replace_string_idx_wrap( list, idx, string ) -! class(stringlist_type), intent(inout) :: list -! type(stringlist_index_type), intent(in) :: idx -! character(len=*), intent(in) :: string - -! integer :: idxpos - -! idxpos = merge( idx%offset, list%size + idx%offset, idx%head ) - -! call list%replace( idxpos, string ) -! end subroutine replace_string_idx_wrap - -! subroutine replace_string_int_impl( list, idx, string ) -! class(stringlist_type), intent(inout) :: list -! integer, intent(in) :: idx -! character(len=*), intent(in) :: string - -! integer :: idxpos - -! if ( idx < 1 .or. idx > list%size ) then -! return -! endif - -! list%string(idx)%value = string -! end subroutine replace_string_int_impl - -! subroutine replace_string_idx_idx_wrap( list, first, last, string ) -! class(stringlist_type), intent(inout) :: list -! type(stringlist_index_type), intent(in) :: first -! type(stringlist_index_type), intent(in) :: last -! character(len=*), intent(in) :: string - -! integer :: firstpos, lastpos - -! firstpos = merge( first%offset, list%size + first%offset, first%head ) -! lastpos = merge( last%offset, list%size + last%offset, last%head ) - -! call list%replace( firstpos, lastpos, string ) -! end subroutine replace_string_idx_idx_wrap - -! subroutine replace_string_int_idx_wrap( list, first, last, string ) -! class(stringlist_type), intent(inout) :: list -! integer, intent(in) :: first -! type(stringlist_index_type), intent(in) :: last -! character(len=*), intent(in) :: string - -! integer :: lastpos - -! lastpos = merge( last%offset, list%size + last%offset, last%head ) - -! call list%replace( first, lastpos, string ) -! end subroutine replace_string_int_idx_wrap - -! subroutine replace_string_idx_int_wrap( list, first, last, string ) -! class(stringlist_type), intent(inout) :: list -! type(stringlist_index_type), intent(in) :: first -! integer, intent(in) :: last -! character(len=*), intent(in) :: string - -! integer :: firstpos - -! firstpos = merge( first%offset, list%size + first%offset, first%head ) - -! call list%replace( firstpos, last, string ) -! end subroutine replace_string_idx_int_wrap - -! subroutine replace_string_int_int_impl( list, first, last, string ) -! class(stringlist_type), intent(inout) :: list -! integer, intent(in) :: first -! integer, intent(in) :: last -! character(len=*), intent(in) :: string - -! if ( first > list%size .or. last < 1 ) then -! return -! endif -! if ( first > last ) then -! return -! endif - -! call list%delete( first, last ) -! call list%insert( first, string ) -! end subroutine replace_string_int_int_impl - - -! subroutine replace_stringlist_idx_idx_wrap( list, first, last, slist ) -! class(stringlist_type), intent(inout) :: list -! type(stringlist_index_type), intent(in) :: first -! type(stringlist_index_type), intent(in) :: last -! class(stringlist_type), intent(in) :: slist - -! integer :: firstpos, lastpos - -! firstpos = merge( first%offset, list%size + first%offset, first%head ) -! lastpos = merge( last%offset, list%size + last%offset, last%head ) - -! call list%replace( firstpos, lastpos, slist ) -! end subroutine replace_stringlist_idx_idx_wrap - -! subroutine replace_stringlist_int_idx_wrap( list, first, last, slist ) -! class(stringlist_type), intent(inout) :: list -! integer, intent(in) :: first -! type(stringlist_index_type), intent(in) :: last -! class(stringlist_type), intent(in) :: slist - -! integer :: lastpos - -! lastpos = merge( last%offset, list%size + last%offset, last%head ) - -! call list%replace( first, lastpos, slist ) -! end subroutine replace_stringlist_int_idx_wrap - -! subroutine replace_stringlist_idx_int_wrap( list, first, last, slist ) -! class(stringlist_type), intent(inout) :: list -! type(stringlist_index_type), intent(in) :: first -! integer, intent(in) :: last -! class(stringlist_type), intent(in) :: slist - -! integer :: firstpos - -! firstpos = merge( first%offset, list%size + first%offset, first%head ) - -! call list%replace( firstpos, last, slist ) -! end subroutine replace_stringlist_idx_int_wrap - -! subroutine replace_stringlist_int_int_impl( list, first, last, slist ) -! class(stringlist_type), intent(inout) :: list -! integer, intent(in) :: first -! integer, intent(in) :: last -! class(stringlist_type), intent(in) :: slist - -! if ( first > list%size .or. last < 1 ) then -! return -! endif -! if ( first > last ) then -! return -! endif - -! call list%delete( first, last ) -! call list%insert( first, slist ) -! end subroutine replace_stringlist_int_int_impl - - -! subroutine replace_stringarray_idx_idx_wrap( list, first, last, sarray ) -! class(stringlist_type), intent(inout) :: list -! type(stringlist_index_type), intent(in) :: first -! type(stringlist_index_type), intent(in) :: last -! character(len=*), dimension(:), intent(in) :: sarray - -! integer :: firstpos, lastpos - -! firstpos = merge( first%offset, list%size + first%offset, first%head ) -! lastpos = merge( last%offset, list%size + last%offset, last%head ) - -! call list%replace( firstpos, lastpos, sarray ) -! end subroutine replace_stringarray_idx_idx_wrap - -! subroutine replace_stringarray_int_idx_wrap( list, first, last, sarray ) -! class(stringlist_type), intent(inout) :: list -! integer, intent(in) :: first -! type(stringlist_index_type), intent(in) :: last -! character(len=*), dimension(:), intent(in) :: sarray - -! integer :: lastpos - -! lastpos = merge( last%offset, list%size + last%offset, last%head ) - -! call list%replace( first, lastpos, sarray ) -! end subroutine replace_stringarray_int_idx_wrap - -! subroutine replace_stringarray_idx_int_wrap( list, first, last, sarray ) -! class(stringlist_type), intent(inout) :: list -! type(stringlist_index_type), intent(in) :: first -! integer, intent(in) :: last -! character(len=*), dimension(:), intent(in) :: sarray - -! integer :: firstpos - -! firstpos = merge( first%offset, list%size + first%offset, first%head ) - -! call list%replace( firstpos, last, sarray ) -! end subroutine replace_stringarray_idx_int_wrap - -! subroutine replace_stringarray_int_int_impl( list, first, last, sarray ) -! class(stringlist_type), intent(inout) :: list -! integer, intent(in) :: first -! integer, intent(in) :: last -! character(len=*), dimension(:), intent(in) :: sarray - -! if ( first > list%size .or. last < 1 ) then -! return -! endif -! if ( first > last ) then -! return -! endif - -! call list%delete( first, last ) -! call list%insert( first, sarray ) -! end subroutine replace_stringarray_int_int_impl end module stdlib_stringlist From 4bf2738c483603feb98aa107e31f4733f68a6951 Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Thu, 29 Jul 2021 00:32:13 +0530 Subject: [PATCH 10/40] removed top comments --- src/stdlib_stringlist.f90 | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/stdlib_stringlist.f90 b/src/stdlib_stringlist.f90 index 4af056d1e..49220b0d6 100644 --- a/src/stdlib_stringlist.f90 +++ b/src/stdlib_stringlist.f90 @@ -4,17 +4,6 @@ ! ! Note: very preliminary ! -! TODO: -! insert( list_end, ... ) in an empty list? -! concatenate two string lists -! -! Not implemented yet: -! insert a list or an array of character strings -! replace a string, list or an array of character strings -! concatenate a list with another list or an array -! -! Limited to implemented routines -! module stdlib_stringlist use stdlib_string_type, only: string_type !, move use stdlib_math, only: clip From 5f8c4848288c954fc08fad36b18215f49ce9f2f6 Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Sun, 1 Aug 2021 02:23:13 +0530 Subject: [PATCH 11/40] resolved a bug in get, improved the implementation of the design --- src/stdlib_stringlist.f90 | 193 +++++++++++++++++++++----------------- 1 file changed, 108 insertions(+), 85 deletions(-) diff --git a/src/stdlib_stringlist.f90 b/src/stdlib_stringlist.f90 index 49220b0d6..05863b66f 100644 --- a/src/stdlib_stringlist.f90 +++ b/src/stdlib_stringlist.f90 @@ -2,12 +2,22 @@ ! Module for storing and manipulating list of strings ! The strings may have arbitrary lengths, not necessarily the same ! -! Note: very preliminary +! insert AT: Inserts an element BEFORE the element present currently at the asked index +! for forward indexes, otherwise +! Inserts an element AFTER the element present currently at the asked index +! for backward indexes +! In other words, after insertion the element will be present at the asked index +! for both forward and backward indexes +! insert BEFORE: Inserts an element BEFORE the element present currently at the asked index +! insert AFTER: Inserts an element AFTER the element present currently at the asked index +! +! Note the distinction between AT and BEFORE in the module. Care has been taken to keep it consistent +! throughout the PR ! module stdlib_stringlist use stdlib_string_type, only: string_type !, move use stdlib_math, only: clip - use stdlib_optval, only: optval + ! use stdlib_optval, only: optval implicit none private @@ -47,32 +57,37 @@ module stdlib_stringlist contains private - procedure :: copy => create_copy + procedure :: copy => create_copy - procedure, public :: destroy => destroy_list + procedure, public :: destroy => destroy_list - procedure, public :: len => length_list + procedure, public :: len => length_list - procedure :: capacity => capacity_list + procedure :: capacity => capacity_list - procedure :: to_idxn => convert_to_idxn + procedure :: to_future_at_idxn => convert_to_future_at_idxn - procedure :: insert_char_idx => insert_char_idx_wrap - procedure :: insert_string_idx => insert_string_idx_wrap - procedure :: insert_stringlist_idx => insert_stringlist_idx_wrap - procedure :: insert_chararray_idx => insert_chararray_idx_wrap - procedure :: insert_stringarray_idx => insert_stringarray_idx_wrap - generic, public :: insert => insert_char_idx, & - insert_string_idx, & - insert_stringlist_idx, & - insert_chararray_idx, & - insert_stringarray_idx + procedure, public :: to_current_idxn => convert_to_current_idxn - procedure :: insert_string_int => insert_string_int_impl - procedure :: insert_stringlist_int => insert_stringlist_int_impl - procedure :: insert_chararray_int => insert_chararray_int_impl - procedure :: insert_stringarray_int => insert_stringarray_int_impl + procedure :: insert_at_char_idx => insert_at_char_idx_wrap + procedure :: insert_at_string_idx => insert_at_string_idx_wrap + procedure :: insert_at_stringlist_idx => insert_at_stringlist_idx_wrap + procedure :: insert_at_chararray_idx => insert_at_chararray_idx_wrap + procedure :: insert_at_stringarray_idx => insert_at_stringarray_idx_wrap + generic, public :: insert_at => insert_at_char_idx, & + insert_at_string_idx, & + insert_at_stringlist_idx, & + insert_at_chararray_idx, & + insert_at_stringarray_idx + procedure :: insert_before_string_int => insert_before_string_int_impl + procedure :: insert_before_stringlist_int => insert_before_stringlist_int_impl + procedure :: insert_before_chararray_int => insert_before_chararray_int_impl + procedure :: insert_before_stringarray_int => insert_before_stringarray_int_impl + generic :: insert_before => insert_before_string_int, & + insert_before_stringlist_int, & + insert_before_chararray_int, & + insert_before_stringarray_int ! procedure :: get_string_int => get_string_int_impl procedure :: get_string_idx => get_string_idx_wrap generic, public :: get => get_string_idx @@ -115,6 +130,7 @@ pure function backward_index(idx) end function backward_index + !> Returns a deep copy of the stringlist 'original' pure function create_copy( original ) class(stringlist_type), intent(in) :: original type(stringlist_type) :: create_copy @@ -142,7 +158,7 @@ function append_string( list, string ) type(stringlist_type) :: append_string append_string = list%copy() - call append_string%insert( list_tail, string ) + call append_string%insert_at( list_tail, string ) end function append_string @@ -165,7 +181,7 @@ function prepend_string( string, list ) type(stringlist_type) :: prepend_string prepend_string = list%copy() - call prepend_string%insert( list_head, string ) + call prepend_string%insert_at( list_head, string ) end function prepend_string @@ -177,7 +193,7 @@ function append_stringlist( list, slist ) type(stringlist_type) :: append_stringlist append_stringlist = list%copy() - call append_stringlist%insert( list_tail, slist ) + call append_stringlist%insert_at( list_tail, slist ) end function append_stringlist @@ -189,7 +205,7 @@ function append_stringarray( list, sarray ) type(stringlist_type) :: append_stringarray append_stringarray = list%copy() - call append_stringarray%insert( list_tail, sarray ) + call append_stringarray%insert_at( list_tail, sarray ) end function append_stringarray @@ -201,7 +217,7 @@ function prepend_stringarray( sarray, list ) type(stringlist_type) :: prepend_stringarray prepend_stringarray = list%copy() - call prepend_stringarray%insert( list_head, sarray ) + call prepend_stringarray%insert_at( list_head, sarray ) end function prepend_stringarray @@ -250,93 +266,111 @@ pure integer function capacity_list( list ) end function capacity_list - ! to_idxn: + ! to_future_at_idxn: !> Version: experimental !> - !> Converts a forward index or backward index to its equivalent integer index + !> Converts a forward index OR a backward index to an integer index at + !> which the new element will be present post insertion (i.e. in future) !> Returns an integer - pure integer function convert_to_idxn( list, idx ) + pure integer function convert_to_future_at_idxn( list, idx ) !> Not a part of public API class(stringlist_type), intent(in) :: list type(stringlist_index_type), intent(in) :: idx - convert_to_idxn = merge( idx%offset, list%len() + 2 - idx%offset, idx%forward ) + ! Formula: merge( fidx( x ) - ( list_head - 1 ), len - bidx( x ) + ( list_tail - 1 ) + 2, ... ) + convert_to_future_at_idxn = merge( idx%offset, list%len() - idx%offset + 2 , idx%forward ) - end function convert_to_idxn + end function convert_to_future_at_idxn - ! insert: + ! to_current_idxn: !> Version: experimental !> - !> Inserts character scalar 'string' at stringlist_index 'idx' in stringlist 'list' + !> Converts a forward index OR backward index to its equivalent integer index idxn + !> Returns an integer + pure integer function convert_to_current_idxn( list, idx ) + !> Not a part of public API + class(stringlist_type), intent(in) :: list + type(stringlist_index_type), intent(in) :: idx + + ! Formula: merge( fidx( x ) - ( list_head - 1 ), len + 1 - bidx( x ) + ( list_tail - 1 ), ... ) + convert_to_current_idxn = merge( idx%offset, list%len() - idx%offset + 1, idx%forward ) + + end function convert_to_current_idxn + + ! insert_at: + + !> Version: experimental + !> + !> Inserts character scalar 'string' AT stringlist_index 'idx' in stringlist 'list' !> Modifies the input stringlist 'list' - subroutine insert_char_idx_wrap( list, idx, string ) + subroutine insert_at_char_idx_wrap( list, idx, string ) class(stringlist_type), intent(inout) :: list type(stringlist_index_type), intent(in) :: idx character(len=*), intent(in) :: string - call list%insert( idx, string_type( string ) ) + call list%insert_at( idx, string_type( string ) ) - end subroutine insert_char_idx_wrap + end subroutine insert_at_char_idx_wrap !> Version: experimental !> - !> Inserts string 'string' at stringlist_index 'idx' in stringlist 'list' + !> Inserts string 'string' AT stringlist_index 'idx' in stringlist 'list' !> Modifies the input stringlist 'list' - subroutine insert_string_idx_wrap( list, idx, string ) + subroutine insert_at_string_idx_wrap( list, idx, string ) class(stringlist_type), intent(inout) :: list type(stringlist_index_type), intent(in) :: idx type(string_type), intent(in) :: string - call list%insert_string_int( list%to_idxn( idx ), string ) + call list%insert_before( list%to_future_at_idxn( idx ), string ) - end subroutine insert_string_idx_wrap + end subroutine insert_at_string_idx_wrap !> Version: experimental !> - !> Inserts stringlist 'slist' at stringlist_index 'idx' in stringlist 'list' + !> Inserts stringlist 'slist' AT stringlist_index 'idx' in stringlist 'list' !> Modifies the input stringlist 'list' - subroutine insert_stringlist_idx_wrap( list, idx, slist ) + subroutine insert_at_stringlist_idx_wrap( list, idx, slist ) class(stringlist_type), intent(inout) :: list type(stringlist_index_type), intent(in) :: idx type(stringlist_type), intent(in) :: slist - call list%insert_stringlist_int( list%to_idxn( idx ), slist ) + call list%insert_before( list%to_future_at_idxn( idx ), slist ) - end subroutine insert_stringlist_idx_wrap + end subroutine insert_at_stringlist_idx_wrap !> Version: experimental !> - !> Inserts chararray 'carray' at stringlist_index 'idx' in stringlist 'list' + !> Inserts chararray 'carray' AT stringlist_index 'idx' in stringlist 'list' !> Modifies the input stringlist 'list' - subroutine insert_chararray_idx_wrap( list, idx, carray ) + subroutine insert_at_chararray_idx_wrap( list, idx, carray ) class(stringlist_type), intent(inout) :: list type(stringlist_index_type), intent(in) :: idx character(len=*), dimension(:), intent(in) :: carray - call list%insert_chararray_int( list%to_idxn( idx ), carray ) + call list%insert_before( list%to_future_at_idxn( idx ), carray ) - end subroutine insert_chararray_idx_wrap + end subroutine insert_at_chararray_idx_wrap !> Version: experimental !> - !> Inserts stringarray 'sarray' at stringlist_index 'idx' in stringlist 'list' + !> Inserts stringarray 'sarray' AT stringlist_index 'idx' in stringlist 'list' !> Modifies the input stringlist 'list' - subroutine insert_stringarray_idx_wrap( list, idx, sarray ) + subroutine insert_at_stringarray_idx_wrap( list, idx, sarray ) class(stringlist_type), intent(inout) :: list type(stringlist_index_type), intent(in) :: idx type(string_type), dimension(:), intent(in) :: sarray - call list%insert_stringarray_int( list%to_idxn( idx ), sarray ) + call list%insert_before( list%to_future_at_idxn( idx ), sarray ) - end subroutine insert_stringarray_idx_wrap + end subroutine insert_at_stringarray_idx_wrap !> Version: experimental !> - !> Inserts 'positions' number of empty positions at integer index 'idxn' + !> Inserts 'positions' number of empty positions BEFORE integer index 'idxn' !> Modifies the input stringlist 'list' - subroutine insert_empty_positions( list, idxn, positions ) + subroutine insert_before_empty_positions( list, idxn, positions ) !> Not a part of public API class(stringlist_type), intent(inout) :: list integer, intent(inout) :: idxn @@ -348,7 +382,8 @@ subroutine insert_empty_positions( list, idxn, positions ) if (positions > 0) then - idxn = clip( idxn, 1, list%len() + 1 ) + idxn = clip( idxn, 1, list%len() + 1 ) + ! Matlab's infinitely expandable list (Ivan's comment)?? old_len = list%len() new_len = old_len + positions @@ -382,25 +417,13 @@ subroutine insert_empty_positions( list, idxn, positions ) positions = 0 end if - end subroutine insert_empty_positions - -! insert_char_int_impl -- -! Insert a new string into the list - specific implementation -! -! subroutine insert_char_int_impl( list, idx, string ) -! type(stringlist_type), intent(inout) :: list -! integer, intent(in) :: idx -! character(len=*), intent(in) :: string - -! call insert( list, idx, string_type( string ) ) - -! end subroutine insert_char_int_impl + end subroutine insert_before_empty_positions !> Version: experimental !> - !> Inserts string 'string' at integer index 'idxn' in stringlist 'list' + !> Inserts string 'string' BEFORE integer index 'idxn' in the underlying stringarray !> Modifies the input stringlist 'list' - subroutine insert_string_int_impl( list, idxn, string ) + subroutine insert_before_string_int_impl( list, idxn, string ) !> Not a part of public API class(stringlist_type), intent(inout) :: list integer, intent(in) :: idxn @@ -411,17 +434,17 @@ subroutine insert_string_int_impl( list, idxn, string ) work_idxn = idxn positions = 1 - call insert_empty_positions( list, work_idxn, positions ) + call insert_before_empty_positions( list, work_idxn, positions ) list%stringarray(work_idxn) = string - end subroutine insert_string_int_impl + end subroutine insert_before_string_int_impl !> Version: experimental !> - !> Inserts stringlist 'slist' at integer index 'idxn' in stringlist 'list' + !> Inserts stringlist 'slist' BEFORE integer index 'idxn' in the underlying stringarray !> Modifies the input stringlist 'list' - subroutine insert_stringlist_int_impl( list, idxn, slist ) + subroutine insert_before_stringlist_int_impl( list, idxn, slist ) !> Not a part of public API class(stringlist_type), intent(inout) :: list integer, intent(in) :: idxn @@ -433,20 +456,20 @@ subroutine insert_stringlist_int_impl( list, idxn, slist ) work_idxn = idxn positions = slist%len() - call insert_empty_positions( list, work_idxn, positions ) + call insert_before_empty_positions( list, work_idxn, positions ) do i = 1, slist%len() idxnew = work_idxn + i - 1 list%stringarray(idxnew) = slist%stringarray(i) end do - end subroutine insert_stringlist_int_impl + end subroutine insert_before_stringlist_int_impl !> Version: experimental !> - !> Inserts chararray 'carray' at integer index 'idxn' in stringlist 'list' + !> Inserts chararray 'carray' BEFORE integer index 'idxn' in the underlying stringarray !> Modifies the input stringlist 'list' - subroutine insert_chararray_int_impl( list, idxn, carray ) + subroutine insert_before_chararray_int_impl( list, idxn, carray ) !> Not a part of public API class(stringlist_type), intent(inout) :: list integer, intent(in) :: idxn @@ -458,20 +481,20 @@ subroutine insert_chararray_int_impl( list, idxn, carray ) work_idxn = idxn positions = size( carray ) - call insert_empty_positions( list, work_idxn, positions ) + call insert_before_empty_positions( list, work_idxn, positions ) do i = 1, size( carray ) idxnew = work_idxn + i - 1 list%stringarray(idxnew) = string_type( carray(i) ) end do - end subroutine insert_chararray_int_impl + end subroutine insert_before_chararray_int_impl !> Version: experimental !> - !> Inserts stringarray 'sarray' at integer index 'idxn' in stringlist 'list' + !> Inserts stringarray 'sarray' BEFORE integer index 'idxn' in the underlying stringarray !> Modifies the input stringlist 'list' - subroutine insert_stringarray_int_impl( list, idxn, sarray ) + subroutine insert_before_stringarray_int_impl( list, idxn, sarray ) !> Not a part of public API class(stringlist_type), intent(inout) :: list integer, intent(in) :: idxn @@ -483,14 +506,14 @@ subroutine insert_stringarray_int_impl( list, idxn, sarray ) work_idxn = idxn positions = size( sarray ) - call insert_empty_positions( list, work_idxn, positions ) + call insert_before_empty_positions( list, work_idxn, positions ) do i = 1, size( sarray ) idxnew = work_idxn + i - 1 list%stringarray(idxnew) = sarray(i) end do - end subroutine insert_stringarray_int_impl + end subroutine insert_before_stringarray_int_impl ! get: @@ -505,7 +528,7 @@ pure function get_string_idx_wrap( list, idx ) integer :: idxn - idxn = list%to_idxn( idx ) + idxn = list%to_current_idxn( idx ) ! - if the index is out of bounds, return a string_type equivalent to empty string if ( 1 <= idxn .and. idxn <= list%len() ) then From 7af5987f3fca53cc6e3093c2e46ac6b7be1953d8 Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Sun, 1 Aug 2021 02:55:31 +0530 Subject: [PATCH 12/40] resolved a bug in destroy, added test cases --- src/Makefile.manual | 2 +- src/stdlib_stringlist.f90 | 4 +- src/tests/CMakeLists.txt | 1 + src/tests/Makefile.manual | 1 + src/tests/stringlist/CMakeLists.txt | 5 +-- .../{test_insert.f90 => test_insert_at.f90} | 45 ++++++++++--------- 6 files changed, 31 insertions(+), 27 deletions(-) rename src/tests/stringlist/{test_insert.f90 => test_insert_at.f90} (53%) diff --git a/src/Makefile.manual b/src/Makefile.manual index 1d6ae2fb9..81c53a9ad 100644 --- a/src/Makefile.manual +++ b/src/Makefile.manual @@ -156,6 +156,6 @@ stdlib_math_linspace.o: \ stdlib_math_logspace.o: \ stdlib_math_linspace.o stdlib_linalg_outer_product.o: stdlib_linalg.o -stdlib_stringlist.o: stdlib_stringtype.o \ +stdlib_stringlist.o: stdlib_string_type.o \ stdlib_math.o \ stdlib_optval.o diff --git a/src/stdlib_stringlist.f90 b/src/stdlib_stringlist.f90 index 05863b66f..758d4473a 100644 --- a/src/stdlib_stringlist.f90 +++ b/src/stdlib_stringlist.f90 @@ -232,7 +232,9 @@ subroutine destroy_list( list ) class(stringlist_type), intent(out) :: list list%size = 0 - deallocate( list%stringarray ) + if ( allocated( list%stringarray ) ) then + deallocate( list%stringarray ) + end if end subroutine destroy_list diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 7d2286fef..01df5d678 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -18,6 +18,7 @@ add_subdirectory(string) add_subdirectory(system) add_subdirectory(quadrature) add_subdirectory(math) +add_subdirectory(stringlist) ADDTEST(always_skip) set_tests_properties(always_skip PROPERTIES SKIP_RETURN_CODE 77) diff --git a/src/tests/Makefile.manual b/src/tests/Makefile.manual index 7ab184016..b317e2ca6 100644 --- a/src/tests/Makefile.manual +++ b/src/tests/Makefile.manual @@ -11,3 +11,4 @@ all test clean: $(MAKE) -f Makefile.manual --directory=stats $@ $(MAKE) -f Makefile.manual --directory=string $@ $(MAKE) -f Makefile.manual --directory=math $@ + $(MAKE) -f Makefile.manual --directory=stringlist $@ diff --git a/src/tests/stringlist/CMakeLists.txt b/src/tests/stringlist/CMakeLists.txt index 7bf83a41a..216321d0f 100644 --- a/src/tests/stringlist/CMakeLists.txt +++ b/src/tests/stringlist/CMakeLists.txt @@ -1,4 +1 @@ -ADDTEST(insert) -ADDTEST(delete) -ADDTEST(find) -ADDTEST(replace_append) +ADDTEST(insert_at) diff --git a/src/tests/stringlist/test_insert.f90 b/src/tests/stringlist/test_insert_at.f90 similarity index 53% rename from src/tests/stringlist/test_insert.f90 rename to src/tests/stringlist/test_insert_at.f90 index 6aa6b1198..bd6eb616f 100644 --- a/src/tests/stringlist/test_insert.f90 +++ b/src/tests/stringlist/test_insert_at.f90 @@ -2,35 +2,37 @@ ! Test the insertion routine ! program test_insertion - use stdlib_stringlist + use stdlib_stringlist, only: stringlist_type, fidx, bidx, stringlist_index_type, & + & list_head, list_tail + use stdlib_string_type, only: string_type, char type(stringlist_type) :: list, second_list character(len=10), dimension(3) :: sarray - call list%insert( 1, "C" ) - call list%insert( 1, "B" ) - call list%insert( 1, "A" ) + call list%insert_at( fidx(1), "C" ) + call list%insert_at( fidx(1), "B" ) + call list%insert_at( fidx(1), "A" ) write(*,*) 'Expected: A, B, C (3)' call print_list( list ) - call list%insert( 6, "D" ) + call list%insert_at( fidx(1), "D" ) write(*,*) 'Expected: A, B, C, D (4)' call print_list( list ) - call list%insert( -1, "X" ) + call list%insert_at( bidx(1), "X" ) write(*,*) 'Expected: X, A, B, C, D (5)' call print_list( list ) - call list%insert( list_end-1, "Y" ) + call list%insert_at( bidx(2), "Y" ) write(*,*) 'Expected: X, A, B, Y, C, D (6)' call print_list( list ) - call list%insert( list_end+1, "Z" ) + call list%insert_at( list_tail, "Z" ) write(*,*) 'Expected: X, A, B, Y, C, D, Z (7)' call print_list( list ) @@ -40,15 +42,15 @@ program test_insertion ! call renew_list( list ) - call second_list%insert( 1, "SecondA" ) - call second_list%insert( 2, "SecondB" ) + call second_list%insert_at( fidx(1), "SecondA" ) + call second_list%insert_at( fidx(2), "SecondB" ) - call list%insert( 2, second_list ) + call list%insert_at( fidx(2), second_list ) call print_list( list ) call renew_list( list ) - call list%insert( list_after_end, second_list ) + call list%insert_at( list_tail, second_list ) call print_list( list ) ! @@ -60,31 +62,32 @@ program test_insertion sarray(2) = "ThirdB" sarray(3) = "ThirdC" - call list%insert( list_head, sarray ) + call list%insert_at( list_head, sarray ) call print_list( list ) call renew_list( list ) - call list%insert( 2, sarray ) + call list%insert_at( fidx(2), sarray ) call print_list( list ) contains subroutine renew_list( list ) type(stringlist_type), intent(inout) :: list - call list%destroy - call list%insert( 1, "A" ) - call list%insert( 2, "B" ) - call list%insert( 3, "C" ) + call list%destroy() + call list%insert_at( fidx(1), "A" ) + call list%insert_at( fidx(2), "B" ) + call list%insert_at( fidx(3), "C" ) end subroutine renew_list subroutine print_list( list ) type(stringlist_type), intent(in) :: list + integer :: i - write(*,*) list%length() + write(*,*) list%len() - do i = 1,list%length() - write(*,*) '>', list%get(i), '<' + do i = 1, list%len() + write(*,*) '>', char( list%get( fidx(i) ) ), '<' enddo end subroutine print_list From e0e0a9610ff2f9f0d950798801be18eaaf10ab4e Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Sun, 1 Aug 2021 03:13:26 +0530 Subject: [PATCH 13/40] this might resolve the error --- src/tests/stringlist/Makefile.manual | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/tests/stringlist/Makefile.manual diff --git a/src/tests/stringlist/Makefile.manual b/src/tests/stringlist/Makefile.manual new file mode 100644 index 000000000..f781281cb --- /dev/null +++ b/src/tests/stringlist/Makefile.manual @@ -0,0 +1,4 @@ +PROGS_SRC = test_insert_at.f90 + + +include ../Makefile.manual.test.mk From 3534150ad25a0764cdea1cf03f9d0d7916e2ff18 Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Sun, 1 Aug 2021 13:32:22 +0530 Subject: [PATCH 14/40] added equality and inequality operators, added support for chararray in append oeprator --- src/stdlib_stringlist.f90 | 216 ++++++++++++++++++++++-- src/tests/stringlist/test_insert_at.f90 | 13 +- 2 files changed, 207 insertions(+), 22 deletions(-) diff --git a/src/stdlib_stringlist.f90 b/src/stdlib_stringlist.f90 index 758d4473a..0d76ccfcd 100644 --- a/src/stdlib_stringlist.f90 +++ b/src/stdlib_stringlist.f90 @@ -15,13 +15,13 @@ ! throughout the PR ! module stdlib_stringlist - use stdlib_string_type, only: string_type !, move + use stdlib_string_type, only: string_type, char, operator(/=) !, move use stdlib_math, only: clip ! use stdlib_optval, only: optval implicit none private - public :: stringlist_type, operator(//) + public :: stringlist_type, operator(//), operator(==), operator(/=) public :: list_head, list_tail, fidx, bidx, stringlist_index_type type stringlist_index_type @@ -106,8 +106,36 @@ module stdlib_stringlist module procedure prepend_char module procedure prepend_string module procedure append_stringlist - module procedure append_stringarray - module procedure prepend_stringarray + module procedure append_carray + module procedure append_sarray + module procedure prepend_carray + module procedure prepend_sarray + end interface + + !> Version: experimental + !> + !> Compares stringlist for equality with the input entity + !> Returns a logical + !> [Specifications](../page/specs/stdlib_stringlist.html#equality-operator) + interface operator(==) + module procedure eq_stringlist + module procedure eq_stringlist_carray + module procedure eq_stringlist_sarray + module procedure eq_carray_stringlist + module procedure eq_sarray_stringlist + end interface + + !> Version: experimental + !> + !> Compares stringlist for inequality with the input entity + !> Returns a logical + !> [Specifications](../page/specs/stdlib_stringlist.html#inequality-operator) + interface operator(/=) + module procedure ineq_stringlist + module procedure ineq_stringlist_carray + module procedure ineq_stringlist_sarray + module procedure ineq_carray_stringlist + module procedure ineq_sarray_stringlist end interface contains @@ -197,29 +225,183 @@ function append_stringlist( list, slist ) end function append_stringlist + !> Appends chararray 'carray' to the stringlist 'list' + !> Returns a new stringlist + function append_carray( list, carray ) + type(stringlist_type), intent(in) :: list + character(len=*), dimension(:), intent(in) :: carray + type(stringlist_type) :: append_carray + + append_carray = list%copy() + call append_carray%insert_at( list_tail, carray ) + + end function append_carray + !> Appends stringarray 'sarray' to the stringlist 'list' !> Returns a new stringlist - function append_stringarray( list, sarray ) + function append_sarray( list, sarray ) + type(stringlist_type), intent(in) :: list + type(string_type), dimension(:), intent(in) :: sarray + type(stringlist_type) :: append_sarray + + append_sarray = list%copy() + call append_sarray%insert_at( list_tail, sarray ) + + end function append_sarray + + !> Prepends chararray 'carray' to the stringlist 'list' + !> Returns a new stringlist + function prepend_carray( carray, list ) + character(len=*), dimension(:), intent(in) :: carray type(stringlist_type), intent(in) :: list - character(len=*), dimension(:), intent(in) :: sarray - type(stringlist_type) :: append_stringarray + type(stringlist_type) :: prepend_carray - append_stringarray = list%copy() - call append_stringarray%insert_at( list_tail, sarray ) + prepend_carray = list%copy() + call prepend_carray%insert_at( list_head, carray ) - end function append_stringarray + end function prepend_carray !> Prepends stringarray 'sarray' to the stringlist 'list' !> Returns a new stringlist - function prepend_stringarray( sarray, list ) - character(len=*), dimension(:), intent(in) :: sarray - type(stringlist_type), intent(in) :: list - type(stringlist_type) :: prepend_stringarray + function prepend_sarray( sarray, list ) + type(string_type), dimension(:), intent(in) :: sarray + type(stringlist_type), intent(in) :: list + type(stringlist_type) :: prepend_sarray + + prepend_sarray = list%copy() + call prepend_sarray%insert_at( list_head, sarray ) + + end function prepend_sarray + + !> Compares stringlist 'list' for equality with stringlist 'slist' + !> Returns a logical + pure logical function eq_stringlist( list, slist ) + type(stringlist_type), intent(in) :: list + type(stringlist_type), intent(in) :: slist + integer :: i + + eq_stringlist = .false. + if ( list%len() == slist%len() ) then + eq_stringlist = .true. + do i = 1, list%len() + if ( list%stringarray(i) /= slist%stringarray(i) ) then + eq_stringlist = .false. + exit + end if + end do + end if + + end function eq_stringlist + + !> Compares stringlist 'list' for equality with chararray 'carray' + !> Returns a logical + pure logical function eq_stringlist_carray( list, carray ) + type(stringlist_type), intent(in) :: list + character(len=*), dimension(:), intent(in) :: carray + integer :: i + + eq_stringlist_carray = .false. + if ( list%len() == size( carray ) ) then + eq_stringlist_carray = .true. + do i = 1, list%len() + if ( char( list%stringarray(i) ) /= carray(i) ) then + eq_stringlist_carray = .false. + exit + end if + end do + end if + + end function eq_stringlist_carray + + !> Compares stringlist 'list' for equality with stringarray 'sarray' + !> Returns a logical + pure logical function eq_stringlist_sarray( list, sarray ) + type(stringlist_type), intent(in) :: list + type(string_type), dimension(:), intent(in) :: sarray + integer :: i + + eq_stringlist_sarray = .false. + if ( list%len() == size( sarray ) ) then + eq_stringlist_sarray = .true. + do i = 1, list%len() + if ( list%stringarray(i) /= sarray(i) ) then + eq_stringlist_sarray = .false. + exit + end if + end do + end if + + end function eq_stringlist_sarray + + !> Compares stringlist 'list' for equality with chararray 'carray' + !> Returns a logical + pure logical function eq_carray_stringlist( carray, list ) + character(len=*), dimension(:), intent(in) :: carray + type(stringlist_type), intent(in) :: list + + eq_carray_stringlist = ( list == carray ) + + end function eq_carray_stringlist + + !> Compares stringlist 'list' for equality with stringarray 'sarray' + !> Returns a logical + pure logical function eq_sarray_stringlist( sarray, list ) + type(string_type), dimension(:), intent(in) :: sarray + type(stringlist_type), intent(in) :: list + + eq_sarray_stringlist = ( list == sarray ) + + end function eq_sarray_stringlist + + !> Compares stringlist 'list' for inequality with stringlist 'slist' + !> Returns a logical + pure logical function ineq_stringlist( list, slist ) + type(stringlist_type), intent(in) :: list + type(stringlist_type), intent(in) :: slist + + ineq_stringlist = .not.( list == slist ) + + end function ineq_stringlist + + !> Compares stringlist 'list' for inequality with chararray 'carray' + !> Returns a logical + pure logical function ineq_stringlist_carray( list, carray ) + type(stringlist_type), intent(in) :: list + character(len=*), dimension(:), intent(in) :: carray + + ineq_stringlist_carray = .not.( list == carray ) + + end function ineq_stringlist_carray + + !> Compares stringlist 'list' for inequality with stringarray 'sarray' + !> Returns a logical + pure logical function ineq_stringlist_sarray( list, sarray ) + type(stringlist_type), intent(in) :: list + type(string_type), dimension(:), intent(in) :: sarray + + ineq_stringlist_sarray = .not.( list == sarray ) + + end function ineq_stringlist_sarray + + !> Compares stringlist 'list' for inequality with chararray 'carray' + !> Returns a logical + pure logical function ineq_carray_stringlist( carray, list ) + character(len=*), dimension(:), intent(in) :: carray + type(stringlist_type), intent(in) :: list + + ineq_carray_stringlist = .not.( carray == list) + + end function ineq_carray_stringlist + + !> Compares stringlist 'list' for inequality with stringarray 'sarray' + !> Returns a logical + pure logical function ineq_sarray_stringlist( sarray, list ) + type(string_type), dimension(:), intent(in) :: sarray + type(stringlist_type), intent(in) :: list - prepend_stringarray = list%copy() - call prepend_stringarray%insert_at( list_head, sarray ) + ineq_sarray_stringlist = .not.( sarray == list ) - end function prepend_stringarray + end function ineq_sarray_stringlist ! destroy: diff --git a/src/tests/stringlist/test_insert_at.f90 b/src/tests/stringlist/test_insert_at.f90 index bd6eb616f..87d6ad037 100644 --- a/src/tests/stringlist/test_insert_at.f90 +++ b/src/tests/stringlist/test_insert_at.f90 @@ -2,8 +2,8 @@ ! Test the insertion routine ! program test_insertion - use stdlib_stringlist, only: stringlist_type, fidx, bidx, stringlist_index_type, & - & list_head, list_tail + use stdlib_stringlist, only: stringlist_type, stringlist_index_type, fidx, bidx, list_head, & + & list_tail, operator(//), operator(==) use stdlib_string_type, only: string_type, char type(stringlist_type) :: list, second_list @@ -17,19 +17,19 @@ program test_insertion write(*,*) 'Expected: A, B, C (3)' call print_list( list ) - call list%insert_at( fidx(1), "D" ) + call list%insert_at( list_tail, "D" ) write(*,*) 'Expected: A, B, C, D (4)' call print_list( list ) - call list%insert_at( bidx(1), "X" ) + call list%insert_at( fidx(1), "X" ) write(*,*) 'Expected: X, A, B, C, D (5)' call print_list( list ) call list%insert_at( bidx(2), "Y" ) - write(*,*) 'Expected: X, A, B, Y, C, D (6)' + write(*,*) 'Expected: X, A, B, C, Y, D (6)' call print_list( list ) call list%insert_at( list_tail, "Z" ) @@ -78,6 +78,9 @@ subroutine renew_list( list ) call list%insert_at( fidx(1), "A" ) call list%insert_at( fidx(2), "B" ) call list%insert_at( fidx(3), "C" ) + write(*,*) '===>', list == ["A", "B", "C"], '<===' + write(*,*) '===>', ["A", "B", "C"] == list, '<===' + end subroutine renew_list subroutine print_list( list ) From b577a54a05759b66ba8e8c4c6df47fd5a8f37854 Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Sun, 1 Aug 2021 21:48:43 +0530 Subject: [PATCH 15/40] added first test case --- src/stdlib_stringlist.f90 | 4 +- src/tests/stringlist/test_delete.f90 | 57 --------- src/tests/stringlist/test_find.f90 | 72 ----------- src/tests/stringlist/test_insert_at.f90 | 123 ++++++------------- src/tests/stringlist/test_replace_append.f90 | 88 ------------- 5 files changed, 41 insertions(+), 303 deletions(-) delete mode 100644 src/tests/stringlist/test_delete.f90 delete mode 100644 src/tests/stringlist/test_find.f90 delete mode 100644 src/tests/stringlist/test_replace_append.f90 diff --git a/src/stdlib_stringlist.f90 b/src/stdlib_stringlist.f90 index 0d76ccfcd..cc992d083 100644 --- a/src/stdlib_stringlist.f90 +++ b/src/stdlib_stringlist.f90 @@ -15,7 +15,7 @@ ! throughout the PR ! module stdlib_stringlist - use stdlib_string_type, only: string_type, char, operator(/=) !, move + use stdlib_string_type, only: string_type, operator(/=) !, move use stdlib_math, only: clip ! use stdlib_optval, only: optval implicit none @@ -304,7 +304,7 @@ pure logical function eq_stringlist_carray( list, carray ) if ( list%len() == size( carray ) ) then eq_stringlist_carray = .true. do i = 1, list%len() - if ( char( list%stringarray(i) ) /= carray(i) ) then + if ( list%stringarray(i) /= carray(i) ) then eq_stringlist_carray = .false. exit end if diff --git a/src/tests/stringlist/test_delete.f90 b/src/tests/stringlist/test_delete.f90 deleted file mode 100644 index 5c3cf0870..000000000 --- a/src/tests/stringlist/test_delete.f90 +++ /dev/null @@ -1,57 +0,0 @@ -! test_delete.f90 -- -! Test the delete routine -! -program test_deletion - use stdlib_stringlist - - type(stringlist_type) :: list - - - call list%insert( 1, ["A", "B", "C", "D", "E", "F"] ) - - call list%delete( 1, 1 ) - - write(*,*) 'Expected: B, C, D, E, F (5)' - call print_list( list ) - - call list%delete( list_end, list_end ) - - write(*,*) 'Expected: B, C, D, E (4)' - call print_list( list ) - - call list%delete( list_end+1, list_end+1 ) - - write(*,*) 'Expected: B, C, D, E (4)' - call print_list( list ) - - call list%delete( 3, 2 ) - - write(*,*) 'Expected: B, C, D, E (4)' - call print_list( list ) - - call list%delete( 2, 3 ) - - write(*,*) 'Expected: B, E (2)' - call print_list( list ) - -contains -subroutine renew_list( list ) - type(stringlist_type), intent(inout) :: list - - call list%destroy - call list%insert( 1, "A" ) - call list%insert( 2, "B" ) - call list%insert( 3, "C" ) -end subroutine renew_list - -subroutine print_list( list ) - type(stringlist_type), intent(in) :: list - - write(*,*) list%length() - - do i = 1,list%length() - write(*,*) '>', list%get(i), '<' - enddo -end subroutine print_list - -end program test_deletion diff --git a/src/tests/stringlist/test_find.f90 b/src/tests/stringlist/test_find.f90 deleted file mode 100644 index 3db7bd806..000000000 --- a/src/tests/stringlist/test_find.f90 +++ /dev/null @@ -1,72 +0,0 @@ -! test_find.f90 -- -! Test the various retrieval routines -! -program test_find - use stdlib_stringlist - - type(stringlist_type) :: list, sublist - character(len=:), allocatable :: string - - call list%insert( 1, ["A", "B", "C", "D", "E", "F"] ) - - write(*,*) 'Expected: A' - write(*,*) list%get(1) - write(*,*) list%get(list_head) - write(*,*) 'Expected: B' - write(*,*) list%get(list_head+1) - write(*,*) 'Expected: F' - write(*,*) list%get(list_end) - write(*,*) 'Expected: (nothing)' - write(*,*) list%get(list_end+1) - - call list%destroy - call list%insert( 1, ["AA", "BA", "CA", "AA", "BA", "CA"] ) - write(*,*) 'Expected: 1' - write(*,*) list%index("AA") - write(*,*) 'Expected: 4' - write(*,*) list%index("AA", .true.) - write(*,*) 'Expected: 0' - write(*,*) list%index("XXXX") - - write(*,*) 'Expected: 2' - write(*,*) list%index_sub("B") - write(*,*) 'Expected: 5' - write(*,*) list%index_sub("B", .true.) - write(*,*) 'Expected: 0' - write(*,*) list%index_sub("X") - - write(*,*) 'Expected: 6', list%length() - - sublist = list%range(1, 2) - write(*,*) 'Expected: AA, BA' - call print_list( sublist ) - - sublist = list%range(list_end-1, list_end+2) - write(*,*) 'Expected: BA, CA' - call print_list( sublist ) - - sublist = list%range(-1, 3) - write(*,*) 'Expected: AA, BA, CA' - call print_list( sublist ) - -contains -subroutine renew_list( list ) - type(stringlist_type), intent(inout) :: list - - call list%destroy - call list%insert( 1, "A" ) - call list%insert( 2, "B" ) - call list%insert( 3, "C" ) -end subroutine renew_list - -subroutine print_list( list ) - type(stringlist_type), intent(in) :: list - - write(*,*) list%length() - - do i = 1,list%length() - write(*,*) '>', list%get(i), '<' - enddo -end subroutine print_list - -end program test_find diff --git a/src/tests/stringlist/test_insert_at.f90 b/src/tests/stringlist/test_insert_at.f90 index 87d6ad037..495d095a6 100644 --- a/src/tests/stringlist/test_insert_at.f90 +++ b/src/tests/stringlist/test_insert_at.f90 @@ -1,97 +1,52 @@ -! test_insert.f90 -- -! Test the insertion routine -! -program test_insertion +! SPDX-Identifier: MIT +module test_insert_at + use stdlib_error, only: check + use stdlib_string_type, only: string_type, char, operator(//), operator(==) use stdlib_stringlist, only: stringlist_type, stringlist_index_type, fidx, bidx, list_head, & - & list_tail, operator(//), operator(==) - use stdlib_string_type, only: string_type, char + & list_tail, operator(==), operator(/=) + use stdlib_ascii, only: to_string + implicit none - type(stringlist_type) :: list, second_list - character(len=10), dimension(3) :: sarray - - - call list%insert_at( fidx(1), "C" ) - call list%insert_at( fidx(1), "B" ) - call list%insert_at( fidx(1), "A" ) - - write(*,*) 'Expected: A, B, C (3)' - call print_list( list ) - - call list%insert_at( list_tail, "D" ) - - write(*,*) 'Expected: A, B, C, D (4)' - call print_list( list ) - - call list%insert_at( fidx(1), "X" ) - - write(*,*) 'Expected: X, A, B, C, D (5)' - call print_list( list ) - - call list%insert_at( bidx(2), "Y" ) - - write(*,*) 'Expected: X, A, B, C, Y, D (6)' - call print_list( list ) - - call list%insert_at( list_tail, "Z" ) - - write(*,*) 'Expected: X, A, B, Y, C, D, Z (7)' - call print_list( list ) - - ! - ! Try inserting a second list - ! - call renew_list( list ) - - call second_list%insert_at( fidx(1), "SecondA" ) - call second_list%insert_at( fidx(2), "SecondB" ) - - call list%insert_at( fidx(2), second_list ) - call print_list( list ) - - call renew_list( list ) - - call list%insert_at( list_tail, second_list ) - call print_list( list ) - - ! - ! Try inserting an array - ! - call renew_list( list ) +contains - sarray(1) = "ThirdA" - sarray(2) = "ThirdB" - sarray(3) = "ThirdC" + subroutine test_insert_at_1 + type(stringlist_type) :: first_list + integer :: i, current_length + character(len=:), allocatable :: string - call list%insert_at( list_head, sarray ) - call print_list( list ) + call check( first_list%to_current_idxn( list_tail ) == 0, "test_insert_at_1: list_tail == 0") + call check( first_list%to_current_idxn( list_head ) == 1, "test_insert_at_1: list_head == 1") - call renew_list( list ) + current_length = 0 + do i = -5, 1 + string = to_string( i ) + call first_list%insert_at( fidx(i), string ) + current_length = current_length + 1 - call list%insert_at( fidx(2), sarray ) - call print_list( list ) + call check( first_list%get( fidx(1) ) == string, "test_insert_at_1: get check failed & + & for forward index " // string ) + call check( first_list%get( list_head ) == string, "test_insert_at_1: get list_head check & + & failed for " // string ) + call check( first_list%get( bidx(current_length) ) == string, "test_insert_at_1: get & + & list_head check failed for backward index " // string ) + call check( first_list%get( list_tail ) == to_string(-5), "test_insert_at_1: get list_tail & + & check failed for " // string ) + call check( first_list%to_current_idxn( list_head ) == 1, "") + call check( first_list%to_current_idxn( list_tail ) == current_length, "" ) + call check( first_list%len() == current_length, "test_insert_at_1: length check & + & failed for " // to_string( current_length ) ) -contains -subroutine renew_list( list ) - type(stringlist_type), intent(inout) :: list + end do - call list%destroy() - call list%insert_at( fidx(1), "A" ) - call list%insert_at( fidx(2), "B" ) - call list%insert_at( fidx(3), "C" ) - write(*,*) '===>', list == ["A", "B", "C"], '<===' - write(*,*) '===>', ["A", "B", "C"] == list, '<===' + end subroutine test_insert_at_1 -end subroutine renew_list +end module test_insert_at -subroutine print_list( list ) - type(stringlist_type), intent(in) :: list - integer :: i - write(*,*) list%len() +program tester + use test_insert_at + implicit none - do i = 1, list%len() - write(*,*) '>', char( list%get( fidx(i) ) ), '<' - enddo -end subroutine print_list + call test_insert_at_1 -end program test_insertion +end program tester diff --git a/src/tests/stringlist/test_replace_append.f90 b/src/tests/stringlist/test_replace_append.f90 deleted file mode 100644 index b7c0c26ed..000000000 --- a/src/tests/stringlist/test_replace_append.f90 +++ /dev/null @@ -1,88 +0,0 @@ -! test_replace_append.f90 -- -! Test the replace and append routines -! -program test_replace_append - use stdlib_stringlist - - type(stringlist_type) :: list, newlist - - call list%insert( 1, ["A", "B", "C", "D", "E", "F"] ) - - newlist = 'Long string' // list - - write(*,*) 'Expected: "Long string, A, B, C, D, E, F (7)' - call print_list( newlist ) - - newlist = list // 'Long string' - - write(*,*) 'Expected: A, B, C, D, E, F, "Long string" (7)' - call print_list( newlist ) - - newlist = list // list - - write(*,*) 'Expected: A, B, C, D, E, F (twice, 12 elements)' - call print_list( newlist ) - - newlist = ['AA', 'BB'] // list - write(*,*) 'Expected: AA, BB, A, B, C, D, E, F (8)' - call print_list( newlist ) - - newlist = list // ['AA', 'BB'] - write(*,*) 'Expected: A, B, C, D, E, F, AA, BB (8)' - call print_list( newlist ) - - ! - ! Replace ... quite a variety - ! - newlist = list - call newlist%replace( 1, "New string" ) - write(*,*) 'Expected: "New string", B, C, D, E, F (6)' - call print_list( newlist ) - - newlist = list - call newlist%replace( list_head, "New string" ) - write(*,*) 'Expected: "New string", B, C, D, E, F (6)' - call print_list( newlist ) - - newlist = list - call newlist%replace( list_end, "New string" ) - write(*,*) 'Expected: A, B, C, D, E, F, "New string" (6)' - call print_list( newlist ) - - newlist = list - call newlist%replace( 5, list_end, "X" ) - write(*,*) 'Expected: A, B, C, D, X (5)' - call print_list( newlist ) - - newlist = list - call newlist%replace( 5, list_end-2, "X" ) - write(*,*) 'Expected: A, B, C, D, E, F (6 - no change)' - call print_list( newlist ) - - newlist = list - call newlist%replace( 1, 2, ["WW", "XX", "YY", "ZZ"] ) - write(*,*) 'Expected: WW, XX, YY, ZZ, C, D, E, F (8)' - call print_list( newlist ) - - newlist = list - call newlist%replace( list_end-1, list_end, ["WW", "XX", "YY", "ZZ"] ) - write(*,*) 'Expected: A, B, C, D, WW, XX, YY, ZZ (8)' - call print_list( newlist ) - - newlist = list - call newlist%replace( list_end-1, list_end, list ) - write(*,*) 'Expected: A, B, C, D, A, B, C, D, E, F (10)' - call print_list( newlist ) - -contains -subroutine print_list( list ) - type(stringlist_type), intent(in) :: list - - write(*,*) list%length() - - do i = 1,list%length() - write(*,*) '>', list%get(i), '<' - enddo -end subroutine print_list - -end program test_replace_append From 9bfab34f2b22fc7f9a574572a7a811c069830059 Mon Sep 17 00:00:00 2001 From: Sebastian Ehlert <28669218+awvwgk@users.noreply.github.com> Date: Mon, 2 Aug 2021 14:32:11 +0200 Subject: [PATCH 16/40] Fix manual makefile build --- src/Makefile.manual | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.manual b/src/Makefile.manual index 81c53a9ad..0ed4e2577 100644 --- a/src/Makefile.manual +++ b/src/Makefile.manual @@ -40,7 +40,7 @@ SRC = f18estop.f90 \ stdlib_logger.f90 \ stdlib_quadrature_gauss.f90 \ stdlib_strings.f90 \ - stdlib_stringlist.f90 + stdlib_stringlist.f90 \ $(SRCGEN) LIB = libstdlib.a From 42487ea0a1dbea341c5164a8671740b90c9ceafc Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Mon, 2 Aug 2021 22:42:53 +0530 Subject: [PATCH 17/40] added 2nd test case for insert_at --- src/tests/stringlist/test_insert_at.f90 | 171 +++++++++++++++++++++--- 1 file changed, 152 insertions(+), 19 deletions(-) diff --git a/src/tests/stringlist/test_insert_at.f90 b/src/tests/stringlist/test_insert_at.f90 index 495d095a6..51057ce07 100644 --- a/src/tests/stringlist/test_insert_at.f90 +++ b/src/tests/stringlist/test_insert_at.f90 @@ -1,45 +1,177 @@ ! SPDX-Identifier: MIT module test_insert_at use stdlib_error, only: check - use stdlib_string_type, only: string_type, char, operator(//), operator(==) + use stdlib_string_type, only: string_type, operator(//), operator(==) use stdlib_stringlist, only: stringlist_type, stringlist_index_type, fidx, bidx, list_head, & - & list_tail, operator(==), operator(/=) + & list_tail, operator(//), operator(==), operator(/=) use stdlib_ascii, only: to_string implicit none contains subroutine test_insert_at_1 - type(stringlist_type) :: first_list + type(stringlist_type) :: work_list integer :: i, current_length character(len=:), allocatable :: string + integer, parameter :: first = -5 + integer, parameter :: last = 1 - call check( first_list%to_current_idxn( list_tail ) == 0, "test_insert_at_1: list_tail == 0") - call check( first_list%to_current_idxn( list_head ) == 1, "test_insert_at_1: list_head == 1") + call check( work_list%to_current_idxn( list_tail ) == 0, "test_insert_at_1: list_tail == 0") + call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_1: list_head == 1") + write (*,*) "test_insert_at_1: Starting test case 1!" current_length = 0 - do i = -5, 1 + do i = first, last string = to_string( i ) - call first_list%insert_at( fidx(i), string ) + call work_list%insert_at( fidx(i), string ) current_length = current_length + 1 - call check( first_list%get( fidx(1) ) == string, "test_insert_at_1: get check failed & - & for forward index " // string ) - call check( first_list%get( list_head ) == string, "test_insert_at_1: get list_head check & - & failed for " // string ) - call check( first_list%get( bidx(current_length) ) == string, "test_insert_at_1: get & - & list_head check failed for backward index " // string ) - call check( first_list%get( list_tail ) == to_string(-5), "test_insert_at_1: get list_tail & - & check failed for " // string ) - call check( first_list%to_current_idxn( list_head ) == 1, "") - call check( first_list%to_current_idxn( list_tail ) == current_length, "" ) - call check( first_list%len() == current_length, "test_insert_at_1: length check & - & failed for " // to_string( current_length ) ) + call check( work_list%get( fidx(1) ) == string, "test_insert_at_1:& + & get fidx(1) " // string ) + call check( work_list%get( list_head ) == string, "test_insert_at_1:& + & get list_head " // string ) + call check( work_list%get( bidx(current_length) ) == string, "test_insert_at_1: get& + & bidx(current_length) " // string ) + call check( work_list%get( list_tail ) == to_string(first), "test_insert_at_1: get& + & list_tail " // string ) + + call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_1:& + & to_current_idxn( list_head ) " // to_string( current_length ) ) + call check( work_list%to_current_idxn( list_tail ) == current_length, "test_insert_at_1:& + & to_current_idxn( list_tail ) " // to_string( current_length ) ) + call check( work_list%len() == current_length, "test_insert_at_1: length check "& + & // to_string( current_length ) ) + + end do + + ! compare work_list with [1, 0, -1, -2, -3, -4, -5] + call compare_list( work_list, last, first - 1, 1) + + call work_list%destroy() + current_length = 0 + + write (*,*) "test_insert_at_1: Starting test case 2!" + do i = first, last + string = to_string( i ) + call work_list%insert_at( bidx(i), string ) + current_length = current_length + 1 + + call check( work_list%get( bidx(1) ) == string, "test_insert_at_1:& + & get bidx(1) " // string ) + call check( work_list%get( list_tail ) == string, "test_insert_at_1:& + & get list_tail " // string ) + call check( work_list%get( fidx(current_length) ) == string, "test_insert_at_1: get& + & fidx(current_length) " // string ) + call check( work_list%get( list_head ) == to_string(first), "test_insert_at_1: get& + & list_head " // string ) + + call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_1:& + & to_current_idxn( list_head ) " // to_string( current_length ) ) + call check( work_list%to_current_idxn( list_tail ) == current_length, "test_insert_at_1:& + & to_current_idxn( list_tail ) " // to_string( current_length ) ) + call check( work_list%len() == current_length, "test_insert_at_1: length check "& + & // to_string( current_length ) ) end do + ! compare work_list with [-5, -4, -3, -2, -1, 0, 1] + call compare_list( work_list, first, last + 1, 2) + end subroutine test_insert_at_1 + subroutine test_insert_at_2 + type(stringlist_type) :: work_list + integer :: i, current_length + character(len=:), allocatable :: string + integer, parameter :: first = 2 + integer, parameter :: last = 20 + + write (*,*) "test_insert_at_2: Starting test case 1!" + + current_length = 0 + do i = first, last, 2 + string = to_string( i ) + call work_list%insert_at( fidx(i), string ) + current_length = current_length + 1 + + call check( work_list%get( fidx(current_length) ) == string, "test_insert_at_2:& + & get fidx(current_length) " // string ) + call check( work_list%get( fidx(1) ) == to_string(first), "test_insert_at_2:& + & get fidx(1) " // string ) + call check( work_list%get( list_head ) == to_string(first), "test_insert_at_2:& + & get list_head " // string ) + call check( work_list%get( bidx(1) ) == string, "test_insert_at_2:& + & get bidx(1) " // string ) + call check( work_list%get( bidx(current_length) ) == to_string(first), "test_insert_at_2: get& + & bidx(current_length) " // string ) + call check( work_list%get( list_tail ) == string, "test_insert_at_2: get& + & list_tail " // string ) + + call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_2:& + & to_current_idxn( list_head ) " // to_string( current_length ) ) + call check( work_list%to_current_idxn( list_tail ) == current_length, "test_insert_at_2:& + & to_current_idxn( list_tail ) " // to_string( current_length ) ) + call check( work_list%len() == current_length, "test_insert_at_2: length check "& + & // to_string( current_length ) ) + + end do + + write (*,*) "test_insert_at_2: Starting test case 2!" + + do i = first - 1, last - 1, 2 + string = to_string( i ) + call work_list%insert_at( fidx(i), string ) + current_length = current_length + 1 + + call check( work_list%get( fidx(i) ) == string, "test_insert_at_2:& + & get fidx(current_length) " // string ) + call check( work_list%get( fidx(1) ) == to_string(first - 1), "test_insert_at_2:& + & get fidx(1) " // string ) + call check( work_list%get( list_head ) == to_string(first - 1), "test_insert_at_2:& + & get list_head " // string ) + call check( work_list%get( bidx(1) ) == to_string(last), "test_insert_at_2:& + & get bidx(1) " // string ) + call check( work_list%get( bidx(current_length) ) == to_string(first - 1), "test_insert_at_2: get& + & bidx(current_length) " // string ) + call check( work_list%get( list_tail ) == to_string(last), "test_insert_at_2: get& + & list_tail " // string ) + + call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_2:& + & to_current_idxn( list_head ) " // to_string( current_length ) ) + call check( work_list%to_current_idxn( list_tail ) == current_length, "test_insert_at_2:& + & to_current_idxn( list_tail ) " // to_string( current_length ) ) + call check( work_list%len() == current_length, "test_insert_at_2: length check "& + & // to_string( current_length ) ) + + end do + + ! compare work_list with [1, 2, ..., ..., 19, 20] + call compare_list( work_list, first - 1, last + 1, 3 ) + + end subroutine test_insert_at_2 + + ! compares input stringlist 'list' with an array of consecutive integers + ! array is 'first' inclusive and 'last' exclusive + subroutine compare_list(list, first, last, call_number) + type(stringlist_type), intent(in) :: list + integer, intent(in) :: first, last, call_number + integer :: i, j + + call check( abs( last - first ) == list%len(), "compare_list: length mis-match& + & call_number " // to_string( call_number ) ) + + j = merge(-1, 1, last < first) + do i = 1, list%len() + call check( list%get( fidx(i) ) == to_string( first + ( ( i - 1 ) * j ) ), & + & "compare_list: call_number " // to_string( call_number ) & + & // " fidx( " // to_string( i ) // " )") + call check( list%get( bidx(i) ) == to_string( last - ( i * j ) ), & + & "compare_list: call_number " // to_string( call_number ) & + & // " bidx( " // to_string( i ) // " )") + end do + + end subroutine compare_list + end module test_insert_at @@ -48,5 +180,6 @@ program tester implicit none call test_insert_at_1 + call test_insert_at_2 end program tester From 3ddfa93234b1b7487ca547d88edc9c4c94d751dd Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Mon, 2 Aug 2021 23:03:37 +0530 Subject: [PATCH 18/40] added 3rd test case for insert_at --- src/tests/stringlist/test_insert_at.f90 | 72 +++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/src/tests/stringlist/test_insert_at.f90 b/src/tests/stringlist/test_insert_at.f90 index 51057ce07..a538b066f 100644 --- a/src/tests/stringlist/test_insert_at.f90 +++ b/src/tests/stringlist/test_insert_at.f90 @@ -150,6 +150,77 @@ subroutine test_insert_at_2 end subroutine test_insert_at_2 + subroutine test_insert_at_3 + type(stringlist_type) :: work_list + integer :: i, current_length + character(len=:), allocatable :: string + integer, parameter :: first = 2 + integer, parameter :: last = 20 + + write (*,*) "test_insert_at_3: Starting test case 1!" + + current_length = 0 + do i = first, last, 2 + string = to_string( i ) + call work_list%insert_at( bidx(i), string ) + current_length = current_length + 1 + + call check( work_list%get( bidx(current_length) ) == string, "test_insert_at_3:& + & get bidx(current_length) " // string ) + call check( work_list%get( bidx(1) ) == to_string(first), "test_insert_at_3:& + & get bidx(1) " // string ) + call check( work_list%get( list_tail ) == to_string(first), "test_insert_at_3:& + & get list_tail " // string ) + call check( work_list%get( fidx(1) ) == string, "test_insert_at_3:& + & get fidx(1) " // string ) + call check( work_list%get( fidx(current_length) ) == to_string(first), "test_insert_at_3: get& + & fidx(current_length) " // string ) + call check( work_list%get( list_head ) == string, "test_insert_at_3: get& + & list_head " // string ) + + call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_3:& + & to_current_idxn( list_head ) " // to_string( current_length ) ) + call check( work_list%to_current_idxn( list_tail ) == current_length, "test_insert_at_3:& + & to_current_idxn( list_tail ) " // to_string( current_length ) ) + call check( work_list%len() == current_length, "test_insert_at_3: length check "& + & // to_string( current_length ) ) + + end do + + write (*,*) "test_insert_at_3: Starting test case 2!" + + do i = first - 1, last - 1, 2 + string = to_string( i ) + call work_list%insert_at( bidx(i), string ) + current_length = current_length + 1 + + call check( work_list%get( bidx(i) ) == string, "test_insert_at_3:& + & get bidx(current_length) " // string ) + call check( work_list%get( bidx(1) ) == to_string(first - 1), "test_insert_at_3:& + & get bidx(1) " // string ) + call check( work_list%get( list_tail ) == to_string(first - 1), "test_insert_at_3:& + & get list_tail " // string ) + call check( work_list%get( fidx(1) ) == to_string(last), "test_insert_at_3:& + & get fidx(1) " // string ) + call check( work_list%get( fidx(current_length) ) == to_string(first - 1), "test_insert_at_3: get& + & fidx(current_length) " // string ) + call check( work_list%get( list_head ) == to_string(last), "test_insert_at_3: get& + & list_head " // string ) + + call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_3:& + & to_current_idxn( list_head ) " // to_string( current_length ) ) + call check( work_list%to_current_idxn( list_tail ) == current_length, "test_insert_at_3:& + & to_current_idxn( list_tail ) " // to_string( current_length ) ) + call check( work_list%len() == current_length, "test_insert_at_3: length check "& + & // to_string( current_length ) ) + + end do + + ! compare work_list with [20, 19, ..., ..., 2, 1] + call compare_list( work_list, last, first - 2, 4 ) + + end subroutine test_insert_at_3 + ! compares input stringlist 'list' with an array of consecutive integers ! array is 'first' inclusive and 'last' exclusive subroutine compare_list(list, first, last, call_number) @@ -181,5 +252,6 @@ program tester call test_insert_at_1 call test_insert_at_2 + call test_insert_at_3 end program tester From 872b2cd1875610bd50f69b4bd64097e5ab09be03 Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Tue, 3 Aug 2021 22:51:24 +0530 Subject: [PATCH 19/40] added test case for append prepend --- src/tests/stringlist/CMakeLists.txt | 1 + src/tests/stringlist/Makefile.manual | 3 +- src/tests/stringlist/test_append_prepend.f90 | 215 +++++++++++++++++++ src/tests/stringlist/test_insert_at.f90 | 18 +- 4 files changed, 227 insertions(+), 10 deletions(-) create mode 100644 src/tests/stringlist/test_append_prepend.f90 diff --git a/src/tests/stringlist/CMakeLists.txt b/src/tests/stringlist/CMakeLists.txt index 216321d0f..b0a8f46e9 100644 --- a/src/tests/stringlist/CMakeLists.txt +++ b/src/tests/stringlist/CMakeLists.txt @@ -1 +1,2 @@ ADDTEST(insert_at) +ADDTEST(append_prepend) diff --git a/src/tests/stringlist/Makefile.manual b/src/tests/stringlist/Makefile.manual index f781281cb..8af13b6fe 100644 --- a/src/tests/stringlist/Makefile.manual +++ b/src/tests/stringlist/Makefile.manual @@ -1,4 +1,5 @@ -PROGS_SRC = test_insert_at.f90 +PROGS_SRC = test_insert_at.f90 / + test_append_prepend.f90 include ../Makefile.manual.test.mk diff --git a/src/tests/stringlist/test_append_prepend.f90 b/src/tests/stringlist/test_append_prepend.f90 new file mode 100644 index 000000000..4c28b87b4 --- /dev/null +++ b/src/tests/stringlist/test_append_prepend.f90 @@ -0,0 +1,215 @@ +! SPDX-Identifier: MIT +module test_append_prepend + use stdlib_error, only: check + use stdlib_string_type, only: string_type, operator(//), operator(==) + use stdlib_stringlist, only: stringlist_type, stringlist_index_type, fidx, bidx, list_head, & + & list_tail, operator(//), operator(==), operator(/=) + use stdlib_ascii, only: to_string + implicit none + +contains + + subroutine test_append_prepend_string + type(stringlist_type) :: work_list + type(stringlist_type) :: reference_list + integer :: i + integer, parameter :: first = -100 + integer, parameter :: last = 100 + character(len=:), allocatable :: string + + do i = first, last + string = to_string(i) + work_list = work_list // string + call check( work_list%get( fidx( i - first + 1 ) ) == string_type( string ), & + & "test_append_prepend_string: get fidx( i - first + 1 ) " // string ) + + end do + + call compare_list( work_list, first, last + 1, 1 ) + call check( work_list == [ ( to_string(i), i = first, last ) ], "test_append_prepend_string:& + & work_list == [ ( to_string(i), i = first, last ) ]" ) + call check( [ ( string_type( to_string(i) ), i = first, last ) ] == work_list, & + & "test_append_prepend_string: [ ( string_type( to_string(i) ),& + & i = first, last ) ] == work_list" ) + + do i = last, first, -1 + call check( work_list /= reference_list, "test_append_prepend_string:& + & work_list /= reference_list" ) + call check( reference_list /= work_list, "test_append_prepend_string:& + & reference_list /= work_list" ) + + string = to_string(i) + reference_list = string_type( string ) // reference_list + call check( reference_list%get( bidx( last - i + 1 ) ) == string, & + & "test_append_prepend_string: get bidx( last - i + 1 ) " // string ) + + end do + + call compare_list( reference_list, first, last + 1, 2 ) + call check( reference_list == [ ( string_type( to_string(i) ), i = first, last ) ], "test_append_prepend_string:& + & reference_list == [ ( string_type( to_string(i) ), i = first, last ) ]" ) + call check( [ ( to_string(i), i = first, last ) ] == reference_list, & + & "test_append_prepend_string: [ ( to_string(i), i = first, last ) ] == reference_list" ) + + call check( work_list == reference_list, "test_append_prepend_string:& + & work_list == reference_list" ) + call check( reference_list == work_list, "test_append_prepend_string:& + & reference_list == work_list" ) + + end subroutine test_append_prepend_string + + subroutine test_append_prepend_array + type(stringlist_type) :: work_list + type(stringlist_type) :: reference_list + integer :: i, j + integer, parameter :: first = -100 + integer, parameter :: last = 100 + integer, parameter :: stride = 10 + + do i = first, last - 1, stride + work_list = work_list // [ ( to_string(j), j = i, i + stride - 1) ] + call check( work_list == [ ( to_string(j), j = first, i + stride - 1) ], & + & "test_append_prepend_array: work_list ==& + & [ ( to_string(j), j = first, i + stride - 1) ]" ) + + end do + + work_list = work_list // to_string(last) + + call compare_list( work_list, first, last + 1, 3 ) + call check( work_list == [ ( to_string(i), i = first, last) ], "test_append_prepend_array:& + & work_list == [ ( to_string(i), i = first, last) ]" ) + call check( [ ( string_type( to_string(i) ), i = first, last) ] == work_list, & + & "test_append_prepend_array: [ ( string_type( to_string(i) ), i = first, last) ]& + & == work_list" ) + + do i = last, first + 1, -1 * stride + call check( work_list /= reference_list, "test_append_prepend_array:& + & work_list /= reference_list" ) + call check( reference_list /= work_list, "test_append_prepend_array:& + & reference_list /= work_list" ) + + reference_list = [ ( string_type( to_string(j) ), j = i - stride + 1, i ) ] & + & // reference_list + call check( reference_list == & + & [ ( string_type( to_string(j) ), j = i - stride + 1, last ) ], & + & "test_append_prepend_array: reference_list ==& + & [ ( string_type( to_string(j) ), j = i - stride + 1, last ) ]" ) + + end do + + reference_list = to_string(first) // reference_list + + call compare_list( reference_list, first, last + 1, 4 ) + call check( [ ( string_type( to_string(i) ), i = first, last) ] == reference_list, & + & "test_append_prepend_array:& + & [ ( string_type( to_string(i) ), i = first, last) ] == reference_list" ) + call check( [ ( to_string(i), i = first, last) ] == reference_list, & + & "test_append_prepend_array: [ ( to_string(i), i = first, last) ] == reference_list" ) + + call check( work_list == reference_list, "test_append_prepend_array:& + & work_list == reference_list" ) + call check( reference_list == work_list, "test_append_prepend_array:& + & reference_list == work_list" ) + + end subroutine test_append_prepend_array + + subroutine test_append_prepend_list + type(stringlist_type) :: work_list, reference_list + type(stringlist_type) :: temp_list + integer :: i, j + integer, parameter :: first = -100 + integer, parameter :: last = 100 + integer, parameter :: stride = 10 + + do i = first, last - 1, stride + call temp_list%destroy() + do j = i, i + stride - 1 + call temp_list%insert_at( list_tail, string_type( to_string(j) ) ) + end do + work_list = work_list // temp_list + + call check( work_list == [ ( string_type( to_string(j) ), j = first, i + stride - 1 ) ], & + & "test_append_prepend_list: work_list ==& + & [ ( to_string(j), j = first, i + stride - 1) ]" ) + + end do + + work_list = work_list // to_string(last) + + call compare_list( work_list, first, last + 1, 5 ) + call check( work_list == [ ( to_string(i), i = first, last) ], "test_append_prepend_list:& + & work_list == [ ( to_string(i), i = first, last) ]" ) + call check( [ ( string_type( to_string(i) ), i = first, last) ] == work_list, & + & "test_append_prepend_list: [ ( string_type( to_string(i) ), i = first, last) ]& + & == work_list" ) + + do i = last, first + 1, -1 * stride + call check( work_list /= reference_list, "test_append_prepend_list:& + & work_list /= reference_list" ) + call check( reference_list /= work_list, "test_append_prepend_list:& + & reference_list /= work_list" ) + + call temp_list%destroy() + do j = i - stride + 1, i + call temp_list%insert_at( list_tail, to_string(j) ) + end do + reference_list = temp_list // reference_list + + call check( reference_list == & + & [ ( string_type( to_string(j) ), j = i - stride + 1, last ) ], & + & "test_append_prepend_list: reference_list ==& + & [ ( string_type( to_string(j) ), j = i - stride + 1, last ) ]" ) + + end do + + reference_list = to_string(first) // reference_list + + call compare_list( reference_list, first, last + 1, 6 ) + call check( [ ( string_type( to_string(i) ), i = first, last) ] == reference_list, & + & "test_append_prepend_list:& + & [ ( string_type( to_string(i) ), i = first, last) ] == reference_list" ) + call check( [ ( to_string(i), i = first, last) ] == reference_list, & + & "test_append_prepend_list: [ ( to_string(i), i = first, last) ] == reference_list" ) + + call check( work_list == reference_list, "test_append_prepend_list:& + & work_list == reference_list" ) + call check( reference_list == work_list, "test_append_prepend_list:& + & reference_list == work_list" ) + + end subroutine test_append_prepend_list + + ! compares input stringlist 'list' with an array of consecutive integers + ! array is 'first' inclusive and 'last' exclusive + subroutine compare_list(list, first, last, call_number) + type(stringlist_type), intent(in) :: list + integer, intent(in) :: first, last, call_number + integer :: i, j + + call check( abs( last - first ) == list%len(), "compare_list: length mis-match& + & call_number " // to_string( call_number ) ) + + j = merge(-1, 1, last < first) + do i = 1, list%len() + call check( list%get( fidx(i) ) == to_string( first + ( ( i - 1 ) * j ) ), & + & "compare_list: call_number " // to_string( call_number ) & + & // " fidx( " // to_string( i ) // " )") + call check( list%get( bidx(i) ) == to_string( last - ( i * j ) ), & + & "compare_list: call_number " // to_string( call_number ) & + & // " bidx( " // to_string( i ) // " )") + end do + + end subroutine compare_list + +end module test_append_prepend + + +program tester + use test_append_prepend + implicit none + + call test_append_prepend_string + call test_append_prepend_array + call test_append_prepend_list + +end program tester diff --git a/src/tests/stringlist/test_insert_at.f90 b/src/tests/stringlist/test_insert_at.f90 index a538b066f..712f3910d 100644 --- a/src/tests/stringlist/test_insert_at.f90 +++ b/src/tests/stringlist/test_insert_at.f90 @@ -2,8 +2,7 @@ module test_insert_at use stdlib_error, only: check use stdlib_string_type, only: string_type, operator(//), operator(==) - use stdlib_stringlist, only: stringlist_type, stringlist_index_type, fidx, bidx, list_head, & - & list_tail, operator(//), operator(==), operator(/=) + use stdlib_stringlist, only: stringlist_type, fidx, bidx, list_head, list_tail use stdlib_ascii, only: to_string implicit none @@ -13,7 +12,7 @@ subroutine test_insert_at_1 type(stringlist_type) :: work_list integer :: i, current_length character(len=:), allocatable :: string - integer, parameter :: first = -5 + integer, parameter :: first = -100 integer, parameter :: last = 1 call check( work_list%to_current_idxn( list_tail ) == 0, "test_insert_at_1: list_tail == 0") @@ -44,9 +43,10 @@ subroutine test_insert_at_1 end do - ! compare work_list with [1, 0, -1, -2, -3, -4, -5] + ! compare work_list with [1, 0, -1, ..., ..., -99, -100] call compare_list( work_list, last, first - 1, 1) + call work_list%destroy() call work_list%destroy() current_length = 0 @@ -74,7 +74,7 @@ subroutine test_insert_at_1 end do - ! compare work_list with [-5, -4, -3, -2, -1, 0, 1] + ! compare work_list with [-100, -99, ..., ..., 0, 1] call compare_list( work_list, first, last + 1, 2) end subroutine test_insert_at_1 @@ -84,7 +84,7 @@ subroutine test_insert_at_2 integer :: i, current_length character(len=:), allocatable :: string integer, parameter :: first = 2 - integer, parameter :: last = 20 + integer, parameter :: last = 200 write (*,*) "test_insert_at_2: Starting test case 1!" @@ -145,7 +145,7 @@ subroutine test_insert_at_2 end do - ! compare work_list with [1, 2, ..., ..., 19, 20] + ! compare work_list with [1, 2, ..., ..., 199, 200] call compare_list( work_list, first - 1, last + 1, 3 ) end subroutine test_insert_at_2 @@ -155,7 +155,7 @@ subroutine test_insert_at_3 integer :: i, current_length character(len=:), allocatable :: string integer, parameter :: first = 2 - integer, parameter :: last = 20 + integer, parameter :: last = 200 write (*,*) "test_insert_at_3: Starting test case 1!" @@ -216,7 +216,7 @@ subroutine test_insert_at_3 end do - ! compare work_list with [20, 19, ..., ..., 2, 1] + ! compare work_list with [200, 199, ..., ..., 2, 1] call compare_list( work_list, last, first - 2, 4 ) end subroutine test_insert_at_3 From dd6aea1a572c9100f4ef3ae528090ef3ba4d8095 Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Tue, 3 Aug 2021 22:58:20 +0530 Subject: [PATCH 20/40] cleared the previous documentation for string_list --- doc/specs/stdlib_stringlist.md | 485 +-------------------------------- 1 file changed, 1 insertion(+), 484 deletions(-) diff --git a/doc/specs/stdlib_stringlist.md b/doc/specs/stdlib_stringlist.md index a214ce565..21dd864fe 100644 --- a/doc/specs/stdlib_stringlist.md +++ b/doc/specs/stdlib_stringlist.md @@ -1,487 +1,4 @@ --- title: stringlist --- -# Lists of strings - -[TOC] - -## Introduction - -Fortran has supported variable-length strings since the 2003 standard, -but it does not have a native type to handle collections of strings of -different lengths. Such collections are quite useful though and the -language allows us to define a derived type that can handle such -collections. - -The `stdlib_stringlist` module defines a derived type that is capable of -storing a list of strings and of manipulating them. - -Methods include: - -* inserting strings at a given position -* replacing strings at a given position -* deleting a single string or a range of strings -* retrieving a string or a range of strings at a given position -* finding the position of a particular string or a string which contains some substring -* sorting the list - -## Positions in a list of strings - -The module implements what are effectively infinitely long lists: a position is -represented as a positive integer, but there is no "out-of-bound" index. That is, -the following piece of code will simply work: - -```fortran -type(stringlist_type) :: list - -! Add two strings ... -call list%insert( list_head, "The first string" ) -call list%insert( 20, "The last string" ) - -write(*,*) 'The last: ', list%get(list_end) -write(*,*) 'Beyond that: ', list%get(30) -``` -The special position `list_head` represents *the first element*, though a value -of 1 is equivalent. Likewise, the special position `list_end` represents the position -of the *last* element and the position `list_after_end` the position directly after -the last element. You can use these positions to insert a string before the current -first string that is already in the list or to insert after the last string that -has been inserted. - -If you specify a position beyond the last, the `list%get()` method simply returns an empty -string. The same holds for *zero* or *negative* indices. - -For inserting one or more elements, a *zero* or *negative* index is interpreted to mean the first, -an index beyond the last as the one *after* the last - this means effectively that the element is appended. - -If you do: - -```fortran -call list%insert( 1, 'The first string' ) -call list%insert( -10, 'A new first string' ) -``` - -the second inserted string will become the string at the *first* position (1) and all other strings -are shifted by one: - -```none -element 1: 'A new first string' -element 2: 'The first string' -element 3: ... -``` - -If you need the last but one string, you can do so in this way: - -```fortran -write(*,*) 'The last but one: ', list%get(list_end-1) -``` - -So, it is possible to do simple arithmetic. - - -## The derived type: stringlist_type - -### Status - -Experimental - -### Description - -The type holds a small number of components and gives access to a number of procedures, -some of which are implemented as subroutines, others as functions or as operations. - - -### Public `stringlist_type` methods - -The following methods are defined: - -Method | Class | Description ----------------------|------------|------------ -[`delete`](./stdlib_stringlist.html#delete-delete_one_or_more_strings) | Subroutine | Delete one or more strings from the list -[`destroy`](./stdlib_stringlist.html#destroy_destroy_all_strings_in_the_list) | Subroutine | Destroy the contents of the list -[`get`](./stdlib_stringlist.html#get-get_a_single_string_from_a_list) | Function | Get a string from a particular position -[`index`](./stdlib_stringlist.html#index-find_the_index_of_a_particular_string_in_the_list) | Function | Find the index of a string in a list -[`index_sub`](./stdlib_stringlist.html#index_sub-find_the_index_of_a_particular_string_containing_the_given_substring) | Function | Find the index of a string containing a partilcar substring -[`insert`](./stdlib_stringlist.html#insert-insert_one_or_more_strings_after_a_given_position) | Subroutine | Insert a string or a list after a given position -[`length`](./stdlib_stringlist.html#length-return_the_length_of_the_list) | Function | Return the index of the last set position -[`range`](./stdlib_stringlist.html#range-retrieve_a_range_of_string_from_the_list) | Function | Retrieve a range of strings from the list -[`replace`](./stdlib_stringlist.html#replace-replace_one_or_more_strings_between_two_given_positions) | Subroutine | Replace one or more stringa between two positions -[`sort`](./stdlib_stringlist.html#sort-return_a_sorted_list) | Function | Sort the list and return the result as a new list -[`=`](./stdlib_stringlist.html#assign-copy_the_contents_of_a_list) | Assignment | Copy a list -[`//`](./stdlib_stringlist.html#//-concatenate_a_list_with_one_or_more_strings) | Operation | Concatenate a list with a string or concatenate two lists - - -## Details of the methods - -### `delete` - delete one or more strings - -#### Status - -Experimental - -#### Description - -Delete one or more strings from the list via a given position or positions. - -#### Syntax - -`call list % [[stringlist_type(type):delete(bound)]]( first [, last] )` - -#### Class - -Subroutine - -#### Arguments - -`list`: the stringlist variable from which to delete one or more strings - -`first`: the index of the first string to be deleted - -`last` (optional): the index of the last string to be deleted. If left out, only one string is deleted. -If the value is lower than that of `first`, the range is considered to be empty and nothing is deleted. - - -### `destroy` - destroy all strings in the list - -#### Status - -Experimental - -#### Description - -Destroy the entire contents of the list. As the variable holding the list is simply a derived type, the variable -itself is not destroyed. - -#### Syntax - -`call list % [[stringlist_type(type):destroy(bound)]]` - -#### Class - -Subroutine - -#### Arguments - -`list`: the stringlist variable from which to delete all strings - - -### `get` - get a single string from the list - -#### Status - -Experimental - -#### Description - -Get the string at the given position. - -#### Syntax - -`string = list % [[stringlist_type(type):get(bound) ( idx )]]` - -#### Class - -Function - -#### Arguments - -`list`: the stringlist variable to retrieve a string from - -`idx`: the index of the string to be retrieved (see [`the section on positions`](./stdlib_stringlist.html#position-in-a-list-of-strings) - -#### Result value - -A copy of the string stored at the indicated position. - - -### `index` - find the index of a particular string in the list - -#### Status - -Experimental - -#### Description - -Get the position of the first stored string that matches the given string, if `back` is not present or false. If `back` is -false, return the position of the last stored string that matches. Note that trailing blanks are ignored. - -#### Syntax - -`idx = list % [[stringlist_type(type):index(bound) ( string, back )]]` - -#### Class - -Function - -#### Arguments - -`list`: the stringlist variable to retrieve a string from - -`string`: the string to be found in the list - -`back` (optional): logical argument indicating the first occurrence should be returned (`false`) or the last (`true`) - -#### Result value - -The result is either the index of the string in the list or -1 if the string was not found - -#### Example - -Because trailing blanks are ignored, the following calls will give the same result: - -```fortran - write(*,*) list%index( 'A' ) - write(*,*) list%index( 'A ' ) -``` - - -### `index_sub` - find the index of a string containing the given substring in the list - -#### Status - -Experimental - -#### Description - -Get the position of the first stored string that contains the given substring, if `back` is not present or false. If `back` is -false, return the position of the last stored string that contains it. - -#### Syntax - -`idx = list % [[stringlist_type(type):index_sub(bound) ( substring, back )]]` - -#### Class - -Function - -#### Arguments - -`list`: the stringlist variable to retrieve a string from - -`substring`: the substring in question - -`back` (optional): logical argument indicating the first occurrence should be returned (`false`) or the last (`true`) - -#### Result value - -The result is either the index of the string in the list or -1 if the string was not found - - -### `insert` - insert one or more strings after a given position - -#### Status - -Experimental - -#### Description - -Insert one or more strings at a given position. The position may be anything as explained in the section on positions. -A single string may be inserted, another list of strings or a plain array of strings. In all cases trailing blanks, if any, -are retained. - -#### Syntax - -`idx = list % [[stringlist_type(type):insert(bound) ( idx, string )]]` - -#### Class - -Subroutine - -#### Arguments - -`list`: the stringlist variable to insert the string(s) into - -`idx`: the position after which the strings should be inserted - -`string`: the string to be inserted, a list of strings or a plain array of strings - - -### `length` - return the length of the list - -#### Status - -Experimental - -#### Description - -Return the length of the list, defined as the highest index for which a string has been assigned. You can place strings -in any position without needing to fill in the intervening positions. - -#### Syntax - -`length = list % [[stringlist_type(type):length(bound) ()]]` - -#### Class - -Function - -#### Arguments - -`list`: the stringlist variable to retrieve the length from - -#### Result value - -Returns the highest index of a string that has been set. - - - -### `range` - retrieve a range of strings from the list - -#### Status - -Experimental - -#### Description - -Retrieve the strings occurring between the given positions as a new list. - -#### Syntax - -`rangelist = list % [[stringlist_type(type):range(bound) ( first, last )]]` - -#### Class - -Function - -#### Arguments - -`list`: the stringlist variable to insert the string(s) into - -`first`: the position of the first string to be retrieved - -`last`: the position of the last string to be retrieved - -#### Result value - -The result is a new list containing all the strings that appear from the first to the last position, inclusively. - - - -### `replace` - replace one or more strings between two given positions - -#### Status - -Experimental - -#### Description - -Replace one or more strings between two given positions. The new strings may be given as a single string, a list of -strings or a plain array. - -#### Syntax - -`call list % [[stringlist_type(type):replace(bound) ( first, last, string )]]` - -#### Class - -Subroutine - -#### Arguments - -`list`: the stringlist variable to replace the string(s) in - - -`first`: the position of the first string to be retrieved - -`last`: the position of the last string to be retrieved. If only one string needs to be replaced by another string, -then this argument can be left out. - -`string`: the string to be inserted, a list of strings or a plain array of strings - - - -### `sort` - return a sorted list - -#### Status - -Experimental - -#### Description - -Create a new list consisting of the sorted strings of the given list. The strings are sorted according to ASCII, either -in ascending order or descending order. - -#### Syntax - -`sortedlist = list % [[stringlist_type(type):sort(bound) ( ascending )]]` - -#### Class - -Subroutine - -#### Arguments - -`list`: the stringlist variable of which the contents should be copied - -`ascending` (optional): if not present or true, sort the list in ascending order, otherwise descending - -#### Result value - -The contents of the given list is sorted and then stored in the new list. - - -### `=` - copy the contents of a list - -#### Status - -Experimental - -#### Description - -Copy an existing list to a new one. The original list remains unchanged. - -#### Syntax - -`copylist = list` - -#### Class - -Assignment - -#### Operands - -`list`: the stringlist variable to be copied - - - -### `//` - concatenate a list with one or more strings - -#### Status - -Experimental - -#### Description - -Concatenate a list with a string, a list of strings or a plain array - -#### Syntax - -`concatenatedlist = list // string` - -`concatenatedlist = string // list` - -#### Class - -Assignment - -#### Operands - -`list`: the stringlist variable to be concatenated - -`string`: the string to be concatenated, a list of strings or a plain array of strings - -#### Result value - -A stringlist that contains the concatenation of the two operands. - - - -## TODO - -Additional methods: - -filter - -map - -Suggestions from the discussion +# List of strings From 29182704b41b25dac8795c9b8fe61fdc2db6f544 Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Tue, 3 Aug 2021 23:08:38 +0530 Subject: [PATCH 21/40] '100' is not equal to '100 ' in other compilers --- src/tests/stringlist/test_append_prepend.f90 | 34 +++++++++++--------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/tests/stringlist/test_append_prepend.f90 b/src/tests/stringlist/test_append_prepend.f90 index 4c28b87b4..2182835fe 100644 --- a/src/tests/stringlist/test_append_prepend.f90 +++ b/src/tests/stringlist/test_append_prepend.f90 @@ -26,8 +26,9 @@ subroutine test_append_prepend_string end do call compare_list( work_list, first, last + 1, 1 ) - call check( work_list == [ ( to_string(i), i = first, last ) ], "test_append_prepend_string:& - & work_list == [ ( to_string(i), i = first, last ) ]" ) + call check( work_list == [ ( string_type( to_string(i) ), i = first, last ) ], & + & "test_append_prepend_string: work_list ==& + & [ ( string_type( to_string(i) ), i = first, last ) ]" ) call check( [ ( string_type( to_string(i) ), i = first, last ) ] == work_list, & & "test_append_prepend_string: [ ( string_type( to_string(i) ),& & i = first, last ) ] == work_list" ) @@ -48,8 +49,8 @@ subroutine test_append_prepend_string call compare_list( reference_list, first, last + 1, 2 ) call check( reference_list == [ ( string_type( to_string(i) ), i = first, last ) ], "test_append_prepend_string:& & reference_list == [ ( string_type( to_string(i) ), i = first, last ) ]" ) - call check( [ ( to_string(i), i = first, last ) ] == reference_list, & - & "test_append_prepend_string: [ ( to_string(i), i = first, last ) ] == reference_list" ) + call check( [ ( string_type( to_string(i) ), i = first, last ) ] == reference_list, & + & "test_append_prepend_string: [ ( string_type( to_string(i) ), i = first, last ) ] == reference_list" ) call check( work_list == reference_list, "test_append_prepend_string:& & work_list == reference_list" ) @@ -67,18 +68,19 @@ subroutine test_append_prepend_array integer, parameter :: stride = 10 do i = first, last - 1, stride - work_list = work_list // [ ( to_string(j), j = i, i + stride - 1) ] - call check( work_list == [ ( to_string(j), j = first, i + stride - 1) ], & + work_list = work_list // [ ( string_type( to_string(j) ), j = i, i + stride - 1) ] + call check( work_list == [ ( string_type( to_string(j) ), j = first, i + stride - 1) ], & & "test_append_prepend_array: work_list ==& - & [ ( to_string(j), j = first, i + stride - 1) ]" ) + & [ ( string_type( to_string(j) ), j = first, i + stride - 1) ]" ) end do work_list = work_list // to_string(last) call compare_list( work_list, first, last + 1, 3 ) - call check( work_list == [ ( to_string(i), i = first, last) ], "test_append_prepend_array:& - & work_list == [ ( to_string(i), i = first, last) ]" ) + call check( work_list == [ ( string_type( to_string(i) ), i = first, last) ], & + & "test_append_prepend_array: work_list ==& + & [ ( string_type( to_string(i) ), i = first, last) ]" ) call check( [ ( string_type( to_string(i) ), i = first, last) ] == work_list, & & "test_append_prepend_array: [ ( string_type( to_string(i) ), i = first, last) ]& & == work_list" ) @@ -104,8 +106,9 @@ subroutine test_append_prepend_array call check( [ ( string_type( to_string(i) ), i = first, last) ] == reference_list, & & "test_append_prepend_array:& & [ ( string_type( to_string(i) ), i = first, last) ] == reference_list" ) - call check( [ ( to_string(i), i = first, last) ] == reference_list, & - & "test_append_prepend_array: [ ( to_string(i), i = first, last) ] == reference_list" ) + call check( [ ( string_type( to_string(i) ), i = first, last) ] == reference_list, & + & "test_append_prepend_array: [ ( string_type( to_string(i) ), i = first, last) ]& + & == reference_list" ) call check( work_list == reference_list, "test_append_prepend_array:& & work_list == reference_list" ) @@ -138,8 +141,8 @@ subroutine test_append_prepend_list work_list = work_list // to_string(last) call compare_list( work_list, first, last + 1, 5 ) - call check( work_list == [ ( to_string(i), i = first, last) ], "test_append_prepend_list:& - & work_list == [ ( to_string(i), i = first, last) ]" ) + call check( work_list == [ ( string_type( to_string(i) ), i = first, last) ], "test_append_prepend_list:& + & work_list == [ ( string_type( to_string(i) ), i = first, last) ]" ) call check( [ ( string_type( to_string(i) ), i = first, last) ] == work_list, & & "test_append_prepend_list: [ ( string_type( to_string(i) ), i = first, last) ]& & == work_list" ) @@ -169,8 +172,9 @@ subroutine test_append_prepend_list call check( [ ( string_type( to_string(i) ), i = first, last) ] == reference_list, & & "test_append_prepend_list:& & [ ( string_type( to_string(i) ), i = first, last) ] == reference_list" ) - call check( [ ( to_string(i), i = first, last) ] == reference_list, & - & "test_append_prepend_list: [ ( to_string(i), i = first, last) ] == reference_list" ) + call check( [ ( string_type( to_string(i) ), i = first, last) ] == reference_list, & + & "test_append_prepend_list: [ ( string_type( to_string(i) ), i = first, last) ]& + & == reference_list" ) call check( work_list == reference_list, "test_append_prepend_list:& & work_list == reference_list" ) From 961a2e7d5c79f0dac774e117ecb9341c57a340e3 Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Tue, 3 Aug 2021 23:17:04 +0530 Subject: [PATCH 22/40] Makefile.manual takes backslash instead of slash --- src/tests/stringlist/Makefile.manual | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/stringlist/Makefile.manual b/src/tests/stringlist/Makefile.manual index 8af13b6fe..8140e758c 100644 --- a/src/tests/stringlist/Makefile.manual +++ b/src/tests/stringlist/Makefile.manual @@ -1,4 +1,4 @@ -PROGS_SRC = test_insert_at.f90 / +PROGS_SRC = test_insert_at.f90 \ test_append_prepend.f90 From 9c758c07e81c69d0ecd503a47543fe8558ac94bf Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Thu, 5 Aug 2021 23:53:22 +0530 Subject: [PATCH 23/40] added insert_at test cases for array and stringlist --- src/tests/stringlist/test_insert_at.f90 | 258 ++++++++++++++++++------ 1 file changed, 191 insertions(+), 67 deletions(-) diff --git a/src/tests/stringlist/test_insert_at.f90 b/src/tests/stringlist/test_insert_at.f90 index 712f3910d..0c3bd44a1 100644 --- a/src/tests/stringlist/test_insert_at.f90 +++ b/src/tests/stringlist/test_insert_at.f90 @@ -8,37 +8,37 @@ module test_insert_at contains - subroutine test_insert_at_1 + subroutine test_insert_at_string_1 type(stringlist_type) :: work_list integer :: i, current_length character(len=:), allocatable :: string integer, parameter :: first = -100 integer, parameter :: last = 1 - call check( work_list%to_current_idxn( list_tail ) == 0, "test_insert_at_1: list_tail == 0") - call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_1: list_head == 1") + call check( work_list%to_current_idxn( list_tail ) == 0, "test_insert_at_string_1: list_tail == 0") + call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_string_1: list_head == 1") - write (*,*) "test_insert_at_1: Starting test case 1!" + write (*,*) "test_insert_at_string_1: Starting test case 1!" current_length = 0 do i = first, last string = to_string( i ) call work_list%insert_at( fidx(i), string ) current_length = current_length + 1 - call check( work_list%get( fidx(1) ) == string, "test_insert_at_1:& + call check( work_list%get( fidx(1) ) == string, "test_insert_at_string_1:& & get fidx(1) " // string ) - call check( work_list%get( list_head ) == string, "test_insert_at_1:& + call check( work_list%get( list_head ) == string, "test_insert_at_string_1:& & get list_head " // string ) - call check( work_list%get( bidx(current_length) ) == string, "test_insert_at_1: get& + call check( work_list%get( bidx(current_length) ) == string, "test_insert_at_string_1: get& & bidx(current_length) " // string ) - call check( work_list%get( list_tail ) == to_string(first), "test_insert_at_1: get& + call check( work_list%get( list_tail ) == to_string(first), "test_insert_at_string_1: get& & list_tail " // string ) - call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_1:& + call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_string_1:& & to_current_idxn( list_head ) " // to_string( current_length ) ) - call check( work_list%to_current_idxn( list_tail ) == current_length, "test_insert_at_1:& + call check( work_list%to_current_idxn( list_tail ) == current_length, "test_insert_at_string_1:& & to_current_idxn( list_tail ) " // to_string( current_length ) ) - call check( work_list%len() == current_length, "test_insert_at_1: length check "& + call check( work_list%len() == current_length, "test_insert_at_string_1: length check "& & // to_string( current_length ) ) end do @@ -50,26 +50,26 @@ subroutine test_insert_at_1 call work_list%destroy() current_length = 0 - write (*,*) "test_insert_at_1: Starting test case 2!" + write (*,*) "test_insert_at_string_1: Starting test case 2!" do i = first, last string = to_string( i ) call work_list%insert_at( bidx(i), string ) current_length = current_length + 1 - call check( work_list%get( bidx(1) ) == string, "test_insert_at_1:& + call check( work_list%get( bidx(1) ) == string, "test_insert_at_string_1:& & get bidx(1) " // string ) - call check( work_list%get( list_tail ) == string, "test_insert_at_1:& + call check( work_list%get( list_tail ) == string, "test_insert_at_string_1:& & get list_tail " // string ) - call check( work_list%get( fidx(current_length) ) == string, "test_insert_at_1: get& + call check( work_list%get( fidx(current_length) ) == string, "test_insert_at_string_1: get& & fidx(current_length) " // string ) - call check( work_list%get( list_head ) == to_string(first), "test_insert_at_1: get& + call check( work_list%get( list_head ) == to_string(first), "test_insert_at_string_1: get& & list_head " // string ) - call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_1:& + call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_string_1:& & to_current_idxn( list_head ) " // to_string( current_length ) ) - call check( work_list%to_current_idxn( list_tail ) == current_length, "test_insert_at_1:& + call check( work_list%to_current_idxn( list_tail ) == current_length, "test_insert_at_string_1:& & to_current_idxn( list_tail ) " // to_string( current_length ) ) - call check( work_list%len() == current_length, "test_insert_at_1: length check "& + call check( work_list%len() == current_length, "test_insert_at_string_1: length check "& & // to_string( current_length ) ) end do @@ -77,16 +77,16 @@ subroutine test_insert_at_1 ! compare work_list with [-100, -99, ..., ..., 0, 1] call compare_list( work_list, first, last + 1, 2) - end subroutine test_insert_at_1 + end subroutine test_insert_at_string_1 - subroutine test_insert_at_2 + subroutine test_insert_at_string_2 type(stringlist_type) :: work_list integer :: i, current_length character(len=:), allocatable :: string integer, parameter :: first = 2 integer, parameter :: last = 200 - write (*,*) "test_insert_at_2: Starting test case 1!" + write (*,*) "test_insert_at_string_2: Starting test case 1!" current_length = 0 do i = first, last, 2 @@ -94,53 +94,53 @@ subroutine test_insert_at_2 call work_list%insert_at( fidx(i), string ) current_length = current_length + 1 - call check( work_list%get( fidx(current_length) ) == string, "test_insert_at_2:& + call check( work_list%get( fidx(current_length) ) == string, "test_insert_at_string_2:& & get fidx(current_length) " // string ) - call check( work_list%get( fidx(1) ) == to_string(first), "test_insert_at_2:& + call check( work_list%get( fidx(1) ) == to_string(first), "test_insert_at_string_2:& & get fidx(1) " // string ) - call check( work_list%get( list_head ) == to_string(first), "test_insert_at_2:& + call check( work_list%get( list_head ) == to_string(first), "test_insert_at_string_2:& & get list_head " // string ) - call check( work_list%get( bidx(1) ) == string, "test_insert_at_2:& + call check( work_list%get( bidx(1) ) == string, "test_insert_at_string_2:& & get bidx(1) " // string ) - call check( work_list%get( bidx(current_length) ) == to_string(first), "test_insert_at_2: get& + call check( work_list%get( bidx(current_length) ) == to_string(first), "test_insert_at_string_2: get& & bidx(current_length) " // string ) - call check( work_list%get( list_tail ) == string, "test_insert_at_2: get& + call check( work_list%get( list_tail ) == string, "test_insert_at_string_2: get& & list_tail " // string ) - call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_2:& + call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_string_2:& & to_current_idxn( list_head ) " // to_string( current_length ) ) - call check( work_list%to_current_idxn( list_tail ) == current_length, "test_insert_at_2:& + call check( work_list%to_current_idxn( list_tail ) == current_length, "test_insert_at_string_2:& & to_current_idxn( list_tail ) " // to_string( current_length ) ) - call check( work_list%len() == current_length, "test_insert_at_2: length check "& + call check( work_list%len() == current_length, "test_insert_at_string_2: length check "& & // to_string( current_length ) ) end do - write (*,*) "test_insert_at_2: Starting test case 2!" + write (*,*) "test_insert_at_string_2: Starting test case 2!" do i = first - 1, last - 1, 2 string = to_string( i ) call work_list%insert_at( fidx(i), string ) current_length = current_length + 1 - call check( work_list%get( fidx(i) ) == string, "test_insert_at_2:& + call check( work_list%get( fidx(i) ) == string, "test_insert_at_string_2:& & get fidx(current_length) " // string ) - call check( work_list%get( fidx(1) ) == to_string(first - 1), "test_insert_at_2:& + call check( work_list%get( fidx(1) ) == to_string(first - 1), "test_insert_at_string_2:& & get fidx(1) " // string ) - call check( work_list%get( list_head ) == to_string(first - 1), "test_insert_at_2:& + call check( work_list%get( list_head ) == to_string(first - 1), "test_insert_at_string_2:& & get list_head " // string ) - call check( work_list%get( bidx(1) ) == to_string(last), "test_insert_at_2:& + call check( work_list%get( bidx(1) ) == to_string(last), "test_insert_at_string_2:& & get bidx(1) " // string ) - call check( work_list%get( bidx(current_length) ) == to_string(first - 1), "test_insert_at_2: get& + call check( work_list%get( bidx(current_length) ) == to_string(first - 1), "test_insert_at_string_2: get& & bidx(current_length) " // string ) - call check( work_list%get( list_tail ) == to_string(last), "test_insert_at_2: get& + call check( work_list%get( list_tail ) == to_string(last), "test_insert_at_string_2: get& & list_tail " // string ) - call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_2:& + call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_string_2:& & to_current_idxn( list_head ) " // to_string( current_length ) ) - call check( work_list%to_current_idxn( list_tail ) == current_length, "test_insert_at_2:& + call check( work_list%to_current_idxn( list_tail ) == current_length, "test_insert_at_string_2:& & to_current_idxn( list_tail ) " // to_string( current_length ) ) - call check( work_list%len() == current_length, "test_insert_at_2: length check "& + call check( work_list%len() == current_length, "test_insert_at_string_2: length check "& & // to_string( current_length ) ) end do @@ -148,16 +148,16 @@ subroutine test_insert_at_2 ! compare work_list with [1, 2, ..., ..., 199, 200] call compare_list( work_list, first - 1, last + 1, 3 ) - end subroutine test_insert_at_2 + end subroutine test_insert_at_string_2 - subroutine test_insert_at_3 + subroutine test_insert_at_string_3 type(stringlist_type) :: work_list integer :: i, current_length character(len=:), allocatable :: string integer, parameter :: first = 2 integer, parameter :: last = 200 - write (*,*) "test_insert_at_3: Starting test case 1!" + write (*,*) "test_insert_at_string_3: Starting test case 1!" current_length = 0 do i = first, last, 2 @@ -165,53 +165,53 @@ subroutine test_insert_at_3 call work_list%insert_at( bidx(i), string ) current_length = current_length + 1 - call check( work_list%get( bidx(current_length) ) == string, "test_insert_at_3:& + call check( work_list%get( bidx(current_length) ) == string, "test_insert_at_string_3:& & get bidx(current_length) " // string ) - call check( work_list%get( bidx(1) ) == to_string(first), "test_insert_at_3:& + call check( work_list%get( bidx(1) ) == to_string(first), "test_insert_at_string_3:& & get bidx(1) " // string ) - call check( work_list%get( list_tail ) == to_string(first), "test_insert_at_3:& + call check( work_list%get( list_tail ) == to_string(first), "test_insert_at_string_3:& & get list_tail " // string ) - call check( work_list%get( fidx(1) ) == string, "test_insert_at_3:& + call check( work_list%get( fidx(1) ) == string, "test_insert_at_string_3:& & get fidx(1) " // string ) - call check( work_list%get( fidx(current_length) ) == to_string(first), "test_insert_at_3: get& + call check( work_list%get( fidx(current_length) ) == to_string(first), "test_insert_at_string_3: get& & fidx(current_length) " // string ) - call check( work_list%get( list_head ) == string, "test_insert_at_3: get& + call check( work_list%get( list_head ) == string, "test_insert_at_string_3: get& & list_head " // string ) - call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_3:& + call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_string_3:& & to_current_idxn( list_head ) " // to_string( current_length ) ) - call check( work_list%to_current_idxn( list_tail ) == current_length, "test_insert_at_3:& + call check( work_list%to_current_idxn( list_tail ) == current_length, "test_insert_at_string_3:& & to_current_idxn( list_tail ) " // to_string( current_length ) ) - call check( work_list%len() == current_length, "test_insert_at_3: length check "& + call check( work_list%len() == current_length, "test_insert_at_string_3: length check "& & // to_string( current_length ) ) end do - write (*,*) "test_insert_at_3: Starting test case 2!" + write (*,*) "test_insert_at_string_3: Starting test case 2!" do i = first - 1, last - 1, 2 string = to_string( i ) call work_list%insert_at( bidx(i), string ) current_length = current_length + 1 - call check( work_list%get( bidx(i) ) == string, "test_insert_at_3:& + call check( work_list%get( bidx(i) ) == string, "test_insert_at_string_3:& & get bidx(current_length) " // string ) - call check( work_list%get( bidx(1) ) == to_string(first - 1), "test_insert_at_3:& + call check( work_list%get( bidx(1) ) == to_string(first - 1), "test_insert_at_string_3:& & get bidx(1) " // string ) - call check( work_list%get( list_tail ) == to_string(first - 1), "test_insert_at_3:& + call check( work_list%get( list_tail ) == to_string(first - 1), "test_insert_at_string_3:& & get list_tail " // string ) - call check( work_list%get( fidx(1) ) == to_string(last), "test_insert_at_3:& + call check( work_list%get( fidx(1) ) == to_string(last), "test_insert_at_string_3:& & get fidx(1) " // string ) - call check( work_list%get( fidx(current_length) ) == to_string(first - 1), "test_insert_at_3: get& + call check( work_list%get( fidx(current_length) ) == to_string(first - 1), "test_insert_at_string_3: get& & fidx(current_length) " // string ) - call check( work_list%get( list_head ) == to_string(last), "test_insert_at_3: get& + call check( work_list%get( list_head ) == to_string(last), "test_insert_at_string_3: get& & list_head " // string ) - call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_3:& + call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_string_3:& & to_current_idxn( list_head ) " // to_string( current_length ) ) - call check( work_list%to_current_idxn( list_tail ) == current_length, "test_insert_at_3:& + call check( work_list%to_current_idxn( list_tail ) == current_length, "test_insert_at_string_3:& & to_current_idxn( list_tail ) " // to_string( current_length ) ) - call check( work_list%len() == current_length, "test_insert_at_3: length check "& + call check( work_list%len() == current_length, "test_insert_at_string_3: length check "& & // to_string( current_length ) ) end do @@ -219,7 +219,129 @@ subroutine test_insert_at_3 ! compare work_list with [200, 199, ..., ..., 2, 1] call compare_list( work_list, last, first - 2, 4 ) - end subroutine test_insert_at_3 + end subroutine test_insert_at_string_3 + + subroutine test_insert_at_array + type(stringlist_type) :: work_list + type(stringlist_type) :: reference_list + integer :: i, j + integer, parameter :: first = -100 + integer, parameter :: last = 100 + integer, parameter :: stride = 4 + + write (*,*) "test_insert_at_array: Starting work_list!" + + call work_list%insert_at( list_head, & + & [ ( string_type( to_string(j) ), j = first, first + stride - 1 ) ] ) + + call compare_list( work_list, first, first + stride, 5 ) + + call work_list%insert_at( list_tail, & + & [ ( string_type( to_string(j) ), j = last - stride, last - 1 ) ] ) + + do i = first + stride, last - stride - 1, stride + call work_list%insert_at( fidx( i - first + 1 ), & + & [ ( string_type( to_string(j) ), j = i, i + stride - 1 ) ] ) + end do + + call work_list%insert_at( list_tail, [ to_string(last) ] ) + + call compare_list( work_list, first, last + 1, 6 ) + + write (*,*) "test_insert_at_array: Starting reference_list!" + + call reference_list%insert_at( list_tail, & + & [ ( string_type( to_string(j) ), j = last - stride + 1, last ) ] ) + + call compare_list( reference_list, last - stride + 1, last + 1, 7 ) + + call reference_list%insert_at( list_head, & + & [ ( string_type( to_string(j) ), j = first + 1, first + stride ) ] ) + + do i = last - stride, first + stride + 1, -1 * stride + call reference_list%insert_at( bidx( last - i + 1 ), & + & [ ( string_type( to_string(j) ), j = i - stride + 1, i ) ] ) + end do + + call reference_list%insert_at( list_head, [ to_string(first) ] ) + + call compare_list( reference_list, first, last + 1, 8 ) + + end subroutine test_insert_at_array + + subroutine test_insert_at_list + type(stringlist_type) :: work_list, reference_list + type(stringlist_type) :: temp_list + integer :: i, j + integer, parameter :: first = -100 + integer, parameter :: last = 100 + integer, parameter :: stride = 4 + + write (*,*) "test_insert_at_list: Starting work_list!" + + call temp_list%destroy() + do j = first, first + stride - 1 + call temp_list%insert_at( list_tail, string_type( to_string(j) ) ) + end do + + call work_list%insert_at(list_head, temp_list) + call compare_list( work_list, first, first + stride, 9) + + call temp_list%destroy() + do j = last - 1, last - stride, -1 + call temp_list%insert_at( list_head, string_type( to_string(j) ) ) + end do + + call work_list%insert_at(list_tail, temp_list) + + do i = first + stride, last - stride - 1, stride + call temp_list%destroy() + do j = i, i + stride - 1 + call temp_list%insert_at( list_tail, to_string(j) ) + end do + call work_list%insert_at( fidx( i - first + 1 ), temp_list ) + + end do + + call temp_list%destroy() + call temp_list%insert_at( list_head, to_string(last) ) + call work_list%insert_at( list_tail, temp_list ) + + call compare_list( work_list, first, last + 1, 10 ) + + write (*,*) "test_insert_at_list: Starting reference_list!" + + call temp_list%destroy() + do j = last - stride + 1, last + call temp_list%insert_at( list_tail, to_string(j) ) + end do + + call reference_list%insert_at( list_tail, temp_list ) + call compare_list( reference_list, last - stride + 1, last + 1, 11 ) + + call temp_list%destroy() + do j = first + 1, first + stride + call temp_list%insert_at( list_tail, string_type( to_string(j) ) ) + end do + + call reference_list%insert_at( list_head, temp_list ) + + do i = last - stride, first + stride + 1, -1 * stride + call temp_list%destroy() + do j = i - stride + 1, i + call temp_list%insert_at( list_tail, to_string(j) ) + end do + call reference_list%insert_at( bidx( last - i + 1 ), temp_list ) + + end do + + call temp_list%destroy() + call temp_list%insert_at( list_tail, to_string(first) ) + call reference_list%insert_at( list_head, temp_list ) + + call compare_list( reference_list, first, last + 1, 12 ) + + end subroutine test_insert_at_list ! compares input stringlist 'list' with an array of consecutive integers ! array is 'first' inclusive and 'last' exclusive @@ -250,8 +372,10 @@ program tester use test_insert_at implicit none - call test_insert_at_1 - call test_insert_at_2 - call test_insert_at_3 + call test_insert_at_string_1 + call test_insert_at_string_2 + call test_insert_at_string_3 + call test_insert_at_array + call test_insert_at_list end program tester From 4db28c88527f25cbe7e7f85ee2ea16c1bebe4729 Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Sun, 8 Aug 2021 17:12:00 +0530 Subject: [PATCH 24/40] first draft of documentation: isnert_at, get, len, derived types --- doc/specs/stdlib_stringlist.md | 209 ++++++++++++++++++- src/tests/stringlist/test_append_prepend.f90 | 2 +- 2 files changed, 209 insertions(+), 2 deletions(-) diff --git a/doc/specs/stdlib_stringlist.md b/doc/specs/stdlib_stringlist.md index 21dd864fe..78fe21260 100644 --- a/doc/specs/stdlib_stringlist.md +++ b/doc/specs/stdlib_stringlist.md @@ -1,4 +1,211 @@ --- title: stringlist --- -# List of strings + +# `stdlib_stringlist` module (1-D List of Strings) + +[TOC] + +## Introduction + +The `stdlib_stringlist` module provides with 2 derived types to deal with list of strings. +`stringlist_type` derived type represents a one-dimensional list of variable-length strings which is compatible with Fortran intrinsic character and `stringlist_type` derived type represents an index to access, modify the elements of a stringlist and insert strings to a stringlist. + +## Derived type provided + + +### `stringlist_type` derived type + +The `stringlist_type` derived type represents one-dimensional list of strings. +The internal representation of the list is implementation dependent and is not visible to the user of the module. + +#### Status + +Experimental + + + +### `stringlist_index_type` derived type + +An instance of the derived type `stringlist_index_type` represents either a forward index OR a backward index. +The internal representation is implementation dependent and is not visible to the user of the module. +`list_head` and `list_tail` are 2 special instances of this type representing the head and the tail of a stringlist respectively. +An instance is independent of the stringlist it is used with and hence, an index can be used with multiple stringlists in the same program. + +#### Status + +Experimental + + + +### insert_at + +#### Description + +Inserts the string `string` at the index `idx` such that after insertion is done the newly added element is at index `idx`. + +#### Syntax + +`call [[stdlib_stringlist(module):stringlist_type(type)]]%[[stdlib_stringlist(module):insert_at(generic)]] (idx, string)` + +#### Status + +Experimental. + +#### Class + +Pure subroutine. + +#### Argument + +- `idx`: [[stdlib_stringlist(module):stringlist_index_type(type)]]. + This argument is intent(in). + +- `string`: Character scalar or [[stdlib_string_type(module):string_type(type)]]. + This argument is intent(in). + +#### Result value + +No result. + +#### Example + +```fortran +program demo_insert_at + use stdlib_stringlist, only: stringlist_type, insert_at, stringlist_index_type, fidx, bidx + use stdlib_string_type, only: string_type + implicit none + + type(stringlist_type) :: stringlist + type(stringlist_index_type) :: index + + index = fidx(1) + call stringlist%insert_at( index, "Element No. one" ) + ! stringlist <-- {"Element No. one"} + + index = bidx(1) + call stringlist%insert_at( index, string_type( "Element No. two" ) ) + ! stringlist <-- {"Element No. one", "Element No. two"} + + call stringlist%insert_at( fidx(2), string_type( "Element No. three" ) ) + ! stringlist <-- {"Element No. one", "Element No. three", "Element No. two"} + + call stringlist%insert_at( bidx(1), "Element No. four" ) + ! stringlist <-- {"Element No. one", "Element No. three", "Element No. two", "Element No. four"} + +end program demo_insert_at +``` + + + +### get + +#### Description + +Returns the string present currently at the index `idx` in the given stringlist. If `idx` is out of bounds an empty string is returned. + +#### Syntax + +`res = [[stdlib_stringlist(module):stringlist_type(type)]]%[[stdlib_stringlist(module):get(generic)]] (idx)` + +#### Status + +Experimental. + +#### Class + +Pure function. + +#### Argument + +- `idx`: [[stdlib_stringlist(module):stringlist_index_type(type)]]. + This argument is intent(in). + +#### Result value + +The result is a string of type `string_type`. + +#### Example + +```fortran +program demo_get + use stdlib_stringlist, only: stringlist_type, insert_at, fidx, get + use stdlib_string_type, only: string_type + implicit none + + type(stringlist_type) :: stringlist + type(string_type) :: output + + !> adding 4 elements to the stringlist + call stringlist%insert_at( fidx(1), "Element No. one" ) + call stringlist%insert_at( fidx(1), "Element No. two" ) + call stringlist%insert_at( fidx(1), "Element No. three" ) + call stringlist%insert_at( fidx(1), "Element No. four" ) + ! stringlist <-- {"Element No. four", "Element No. three", "Element No. two", "Element No. one"} + + output = stringlist%get( fidx(1) ) + ! output <-- "Element No. four" + + output = stringlist%get( bidx(1) ) + ! output <-- "Element No. one" + + !> accessing out of bounds index + output = stringlist%get( bidx(5) ) + ! output <-- "" + output = stringlist%get( fidx(0) ) + ! output <-- "" + +end program demo_get +``` + + + +### len + +#### Description + +Returns the number of elements present in the stringlist. + +#### Syntax + +`res = [[stdlib_stringlist(module):stringlist_type(type)]]%[[stdlib_stringlist(module):len()]] ()` + +#### Status + +Experimental. + +#### Class + +Pure function. + +#### Argument + +No arguments. + +#### Result value + +The result is of type `integer`. + +#### Example + +```fortran +program demo_len + use stdlib_stringlist, only: stringlist_type, insert_at, bidx, len + implicit none + + type(stringlist_type) :: stringlist + integer :: output + + output = stringlist%len() + ! output <-- 0 + + !> adding 2 elements to the stringlist + call stringlist%insert_at( bidx(1), "Element No. one" ) + call stringlist%insert_at( bidx(1), "Element No. two" ) + ! stringlist <-- {"Element No. one", "Element No. two"} + + output = stringlist%len() + ! output <-- 2 + +end program demo_len +``` diff --git a/src/tests/stringlist/test_append_prepend.f90 b/src/tests/stringlist/test_append_prepend.f90 index 2182835fe..e21f0bd68 100644 --- a/src/tests/stringlist/test_append_prepend.f90 +++ b/src/tests/stringlist/test_append_prepend.f90 @@ -2,7 +2,7 @@ module test_append_prepend use stdlib_error, only: check use stdlib_string_type, only: string_type, operator(//), operator(==) - use stdlib_stringlist, only: stringlist_type, stringlist_index_type, fidx, bidx, list_head, & + use stdlib_stringlist, only: stringlist_type, fidx, bidx, list_head, & & list_tail, operator(//), operator(==), operator(/=) use stdlib_ascii, only: to_string implicit none From afb318e3809765c598693d276d3e2829db83afb6 Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Sun, 15 Aug 2021 20:51:16 +0530 Subject: [PATCH 25/40] added constructor for carray & sarray, changed intent of clear_list subroutine --- src/stdlib_stringlist.f90 | 77 +++++++++++++++++--- src/tests/stringlist/test_append_prepend.f90 | 4 +- src/tests/stringlist/test_insert_at.f90 | 22 +++--- 3 files changed, 81 insertions(+), 22 deletions(-) diff --git a/src/stdlib_stringlist.f90 b/src/stdlib_stringlist.f90 index cc992d083..026921a8e 100644 --- a/src/stdlib_stringlist.f90 +++ b/src/stdlib_stringlist.f90 @@ -59,7 +59,7 @@ module stdlib_stringlist private procedure :: copy => create_copy - procedure, public :: destroy => destroy_list + procedure, public :: clear => clear_list procedure, public :: len => length_list @@ -88,13 +88,23 @@ module stdlib_stringlist insert_before_stringlist_int, & insert_before_chararray_int, & insert_before_stringarray_int - ! procedure :: get_string_int => get_string_int_impl + procedure :: get_string_idx => get_string_idx_wrap generic, public :: get => get_string_idx - ! get_string_int end type stringlist_type + !> Version: experimental + !> + !> Constructor for stringlist + !> Returns an instance of type stringlist_type + !> [Specifications](../page/specs/stdlib_stringlist.html#stringlist_type) + interface stringlist_type + module procedure new_stringlist + module procedure new_stringlist_carray + module procedure new_stringlist_sarray + end interface + !> Version: experimental !> !> Concatenates stringlist with the input entity @@ -140,8 +150,48 @@ module stdlib_stringlist contains + ! constructor for stringlist_type: + + !> Constructor with no argument + !> Returns a new instance of type stringlist + pure function new_stringlist() + type(stringlist_type) :: new_stringlist + type(string_type), dimension(0) :: sarray + + new_stringlist = stringlist_type( 0, sarray ) + + end function new_stringlist + + !> Constructor to convert chararray to stringlist + !> Returns a new instance of type stringlist + pure function new_stringlist_carray( carray ) + character(len=*), dimension(:), intent(in) :: carray + type(stringlist_type) :: new_stringlist_carray + type(string_type), dimension( size(carray) ) :: sarray + integer :: i + + do i = 1, size(carray) + sarray(i) = string_type( carray(i) ) + end do + + new_stringlist_carray = stringlist_type( sarray ) + + end function new_stringlist_carray + + !> Constructor to convert stringarray to stringlist + !> Returns a new instance of type stringlist + pure function new_stringlist_sarray( sarray ) + type(string_type), dimension(:), intent(in) :: sarray + type(stringlist_type) :: new_stringlist_sarray + + new_stringlist_sarray = stringlist_type( size(sarray), sarray ) + + end function new_stringlist_sarray + + ! constructor for stringlist_index_type: + !> Returns an instance of type 'stringlist_index_type' representing forward index 'idx' - pure function forward_index(idx) + pure function forward_index( idx ) integer, intent(in) :: idx type(stringlist_index_type) :: forward_index @@ -150,7 +200,7 @@ pure function forward_index(idx) end function forward_index !> Returns an instance of type 'stringlist_index_type' representing backward index 'idx' - pure function backward_index(idx) + pure function backward_index( idx ) integer, intent(in) :: idx type(stringlist_index_type) :: backward_index @@ -158,6 +208,8 @@ pure function backward_index(idx) end function backward_index + ! copy + !> Returns a deep copy of the stringlist 'original' pure function create_copy( original ) class(stringlist_type), intent(in) :: original @@ -167,6 +219,8 @@ pure function create_copy( original ) end function create_copy + ! concatenation operator: + !> Appends character scalar 'string' to the stringlist 'list' !> Returns a new stringlist function append_char( list, string ) @@ -273,6 +327,8 @@ function prepend_sarray( sarray, list ) end function prepend_sarray + ! equality operator: + !> Compares stringlist 'list' for equality with stringlist 'slist' !> Returns a logical pure logical function eq_stringlist( list, slist ) @@ -353,6 +409,8 @@ pure logical function eq_sarray_stringlist( sarray, list ) end function eq_sarray_stringlist + ! inequality operator: + !> Compares stringlist 'list' for inequality with stringlist 'slist' !> Returns a logical pure logical function ineq_stringlist( list, slist ) @@ -403,22 +461,21 @@ pure logical function ineq_sarray_stringlist( sarray, list ) end function ineq_sarray_stringlist - ! destroy: + ! clear: !> Version: experimental !> !> Resets stringlist 'list' to an empy stringlist of len 0 !> Modifies the input stringlist 'list' - subroutine destroy_list( list ) - !> TODO: needs a better name?? like clear_list or reset_list - class(stringlist_type), intent(out) :: list + subroutine clear_list( list ) + class(stringlist_type), intent(inout) :: list list%size = 0 if ( allocated( list%stringarray ) ) then deallocate( list%stringarray ) end if - end subroutine destroy_list + end subroutine clear_list ! len: diff --git a/src/tests/stringlist/test_append_prepend.f90 b/src/tests/stringlist/test_append_prepend.f90 index e21f0bd68..7334ee3c7 100644 --- a/src/tests/stringlist/test_append_prepend.f90 +++ b/src/tests/stringlist/test_append_prepend.f90 @@ -126,7 +126,7 @@ subroutine test_append_prepend_list integer, parameter :: stride = 10 do i = first, last - 1, stride - call temp_list%destroy() + call temp_list%clear() do j = i, i + stride - 1 call temp_list%insert_at( list_tail, string_type( to_string(j) ) ) end do @@ -153,7 +153,7 @@ subroutine test_append_prepend_list call check( reference_list /= work_list, "test_append_prepend_list:& & reference_list /= work_list" ) - call temp_list%destroy() + call temp_list%clear() do j = i - stride + 1, i call temp_list%insert_at( list_tail, to_string(j) ) end do diff --git a/src/tests/stringlist/test_insert_at.f90 b/src/tests/stringlist/test_insert_at.f90 index 0c3bd44a1..86cce08bc 100644 --- a/src/tests/stringlist/test_insert_at.f90 +++ b/src/tests/stringlist/test_insert_at.f90 @@ -15,6 +15,8 @@ subroutine test_insert_at_string_1 integer, parameter :: first = -100 integer, parameter :: last = 1 + work_list = stringlist_type() + call check( work_list%len() == 0, "test_insert_at_string_1: constructor" ) call check( work_list%to_current_idxn( list_tail ) == 0, "test_insert_at_string_1: list_tail == 0") call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_string_1: list_head == 1") @@ -46,8 +48,8 @@ subroutine test_insert_at_string_1 ! compare work_list with [1, 0, -1, ..., ..., -99, -100] call compare_list( work_list, last, first - 1, 1) - call work_list%destroy() - call work_list%destroy() + call work_list%clear() + call work_list%clear() current_length = 0 write (*,*) "test_insert_at_string_1: Starting test case 2!" @@ -279,7 +281,7 @@ subroutine test_insert_at_list write (*,*) "test_insert_at_list: Starting work_list!" - call temp_list%destroy() + call temp_list%clear() do j = first, first + stride - 1 call temp_list%insert_at( list_tail, string_type( to_string(j) ) ) end do @@ -287,7 +289,7 @@ subroutine test_insert_at_list call work_list%insert_at(list_head, temp_list) call compare_list( work_list, first, first + stride, 9) - call temp_list%destroy() + call temp_list%clear() do j = last - 1, last - stride, -1 call temp_list%insert_at( list_head, string_type( to_string(j) ) ) end do @@ -295,7 +297,7 @@ subroutine test_insert_at_list call work_list%insert_at(list_tail, temp_list) do i = first + stride, last - stride - 1, stride - call temp_list%destroy() + call temp_list%clear() do j = i, i + stride - 1 call temp_list%insert_at( list_tail, to_string(j) ) end do @@ -303,7 +305,7 @@ subroutine test_insert_at_list end do - call temp_list%destroy() + call temp_list%clear() call temp_list%insert_at( list_head, to_string(last) ) call work_list%insert_at( list_tail, temp_list ) @@ -311,7 +313,7 @@ subroutine test_insert_at_list write (*,*) "test_insert_at_list: Starting reference_list!" - call temp_list%destroy() + call temp_list%clear() do j = last - stride + 1, last call temp_list%insert_at( list_tail, to_string(j) ) end do @@ -319,7 +321,7 @@ subroutine test_insert_at_list call reference_list%insert_at( list_tail, temp_list ) call compare_list( reference_list, last - stride + 1, last + 1, 11 ) - call temp_list%destroy() + call temp_list%clear() do j = first + 1, first + stride call temp_list%insert_at( list_tail, string_type( to_string(j) ) ) end do @@ -327,7 +329,7 @@ subroutine test_insert_at_list call reference_list%insert_at( list_head, temp_list ) do i = last - stride, first + stride + 1, -1 * stride - call temp_list%destroy() + call temp_list%clear() do j = i - stride + 1, i call temp_list%insert_at( list_tail, to_string(j) ) end do @@ -335,7 +337,7 @@ subroutine test_insert_at_list end do - call temp_list%destroy() + call temp_list%clear() call temp_list%insert_at( list_tail, to_string(first) ) call reference_list%insert_at( list_head, temp_list ) From a0c20ccce6d04efac426c732212ba21a03316d9c Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Sun, 15 Aug 2021 23:03:23 +0530 Subject: [PATCH 26/40] replaced copy function with appropriate comments --- src/stdlib_stringlist.f90 | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/src/stdlib_stringlist.f90 b/src/stdlib_stringlist.f90 index 026921a8e..26daf9135 100644 --- a/src/stdlib_stringlist.f90 +++ b/src/stdlib_stringlist.f90 @@ -57,7 +57,6 @@ module stdlib_stringlist contains private - procedure :: copy => create_copy procedure, public :: clear => clear_list @@ -208,17 +207,6 @@ pure function backward_index( idx ) end function backward_index - ! copy - - !> Returns a deep copy of the stringlist 'original' - pure function create_copy( original ) - class(stringlist_type), intent(in) :: original - type(stringlist_type) :: create_copy - - create_copy = original - - end function create_copy - ! concatenation operator: !> Appends character scalar 'string' to the stringlist 'list' @@ -239,7 +227,7 @@ function append_string( list, string ) type(string_type), intent(in) :: string type(stringlist_type) :: append_string - append_string = list%copy() + append_string = list ! Intent: creating a full, deep copy call append_string%insert_at( list_tail, string ) end function append_string @@ -262,7 +250,7 @@ function prepend_string( string, list ) type(stringlist_type), intent(in) :: list type(stringlist_type) :: prepend_string - prepend_string = list%copy() + prepend_string = list ! Intent: creating a full, deep copy call prepend_string%insert_at( list_head, string ) end function prepend_string @@ -274,7 +262,7 @@ function append_stringlist( list, slist ) type(stringlist_type), intent(in) :: slist type(stringlist_type) :: append_stringlist - append_stringlist = list%copy() + append_stringlist = list ! Intent: creating a full, deep copy call append_stringlist%insert_at( list_tail, slist ) end function append_stringlist @@ -286,7 +274,7 @@ function append_carray( list, carray ) character(len=*), dimension(:), intent(in) :: carray type(stringlist_type) :: append_carray - append_carray = list%copy() + append_carray = list ! Intent: creating a full, deep copy call append_carray%insert_at( list_tail, carray ) end function append_carray @@ -298,7 +286,7 @@ function append_sarray( list, sarray ) type(string_type), dimension(:), intent(in) :: sarray type(stringlist_type) :: append_sarray - append_sarray = list%copy() + append_sarray = list ! Intent: creating a full, deep copy call append_sarray%insert_at( list_tail, sarray ) end function append_sarray @@ -310,7 +298,7 @@ function prepend_carray( carray, list ) type(stringlist_type), intent(in) :: list type(stringlist_type) :: prepend_carray - prepend_carray = list%copy() + prepend_carray = list ! Intent: creating a full, deep copy call prepend_carray%insert_at( list_head, carray ) end function prepend_carray @@ -322,7 +310,7 @@ function prepend_sarray( sarray, list ) type(stringlist_type), intent(in) :: list type(stringlist_type) :: prepend_sarray - prepend_sarray = list%copy() + prepend_sarray = list ! Intent: creating a full, deep copy call prepend_sarray%insert_at( list_head, sarray ) end function prepend_sarray From 35b28f53e2b445d433004b479530d2dc856ea821 Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Sun, 15 Aug 2021 23:54:59 +0530 Subject: [PATCH 27/40] solved bug: inserting a list in itself --- src/stdlib_stringlist.f90 | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/stdlib_stringlist.f90 b/src/stdlib_stringlist.f90 index 26daf9135..d8ed0a084 100644 --- a/src/stdlib_stringlist.f90 +++ b/src/stdlib_stringlist.f90 @@ -603,7 +603,7 @@ subroutine insert_before_empty_positions( list, idxn, positions ) !> Not a part of public API class(stringlist_type), intent(inout) :: list integer, intent(inout) :: idxn - integer, intent(inout) :: positions + integer, intent(in) :: positions integer :: i, inew integer :: new_len, old_len @@ -642,8 +642,6 @@ subroutine insert_before_empty_positions( list, idxn, positions ) list%size = new_len - else - positions = 0 end if end subroutine insert_before_empty_positions @@ -659,11 +657,9 @@ subroutine insert_before_string_int_impl( list, idxn, string ) type(string_type), intent(in) :: string integer :: work_idxn - integer :: positions work_idxn = idxn - positions = 1 - call insert_before_empty_positions( list, work_idxn, positions ) + call insert_before_empty_positions( list, work_idxn, 1 ) list%stringarray(work_idxn) = string @@ -681,17 +677,23 @@ subroutine insert_before_stringlist_int_impl( list, idxn, slist ) integer :: i integer :: work_idxn, idxnew - integer :: positions + integer :: pre_length, post_length - work_idxn = idxn - positions = slist%len() - call insert_before_empty_positions( list, work_idxn, positions ) + work_idxn = idxn + pre_length = slist%len() + call insert_before_empty_positions( list, work_idxn, pre_length ) + post_length = slist%len() - do i = 1, slist%len() + do i = 1, min( work_idxn - 1, pre_length ) idxnew = work_idxn + i - 1 list%stringarray(idxnew) = slist%stringarray(i) end do + do i = work_idxn + post_length - pre_length, post_length + idxnew = work_idxn + i - post_length + pre_length - 1 + list%stringarray(idxnew) = slist%stringarray(i) + end do + end subroutine insert_before_stringlist_int_impl !> Version: experimental @@ -706,11 +708,9 @@ subroutine insert_before_chararray_int_impl( list, idxn, carray ) integer :: i integer :: work_idxn, idxnew - integer :: positions work_idxn = idxn - positions = size( carray ) - call insert_before_empty_positions( list, work_idxn, positions ) + call insert_before_empty_positions( list, work_idxn, size( carray ) ) do i = 1, size( carray ) idxnew = work_idxn + i - 1 @@ -731,11 +731,9 @@ subroutine insert_before_stringarray_int_impl( list, idxn, sarray ) integer :: i integer :: work_idxn, idxnew - integer :: positions work_idxn = idxn - positions = size( sarray ) - call insert_before_empty_positions( list, work_idxn, positions ) + call insert_before_empty_positions( list, work_idxn, size( sarray ) ) do i = 1, size( sarray ) idxnew = work_idxn + i - 1 @@ -759,7 +757,7 @@ pure function get_string_idx_wrap( list, idx ) idxn = list%to_current_idxn( idx ) - ! - if the index is out of bounds, return a string_type equivalent to empty string + ! if the index is out of bounds, return a string_type equivalent to empty string if ( 1 <= idxn .and. idxn <= list%len() ) then get_string_idx_wrap = list%stringarray(idxn) From 8ed81c04d15bac054deaab39fe092deee1071e68 Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Mon, 16 Aug 2021 20:48:58 +0530 Subject: [PATCH 28/40] added test cases for constructor stringlist_type() --- src/tests/stringlist/test_insert_at.f90 | 35 ++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/tests/stringlist/test_insert_at.f90 b/src/tests/stringlist/test_insert_at.f90 index 86cce08bc..04fad623b 100644 --- a/src/tests/stringlist/test_insert_at.f90 +++ b/src/tests/stringlist/test_insert_at.f90 @@ -2,7 +2,7 @@ module test_insert_at use stdlib_error, only: check use stdlib_string_type, only: string_type, operator(//), operator(==) - use stdlib_stringlist, only: stringlist_type, fidx, bidx, list_head, list_tail + use stdlib_stringlist, only: stringlist_type, fidx, bidx, list_head, list_tail, operator(==) use stdlib_ascii, only: to_string implicit none @@ -345,6 +345,38 @@ subroutine test_insert_at_list end subroutine test_insert_at_list + subroutine test_constructor + type(stringlist_type) :: work_list + character(len=4), allocatable :: carray(:) + type(string_type), allocatable :: sarray(:) + + write (*,*) "test_constructor: Starting test case 1!" + work_list = stringlist_type() + allocate( carray(0) ) + allocate( sarray(0) ) + call check( work_list == carray, "test_constructor:& + & test_case 1 work_list == carray" ) + call check( work_list == sarray, "test_constructor:& + & test_case 1 work_list == sarray" ) + + write (*,*) "test_constructor: Starting test case 2!" + carray = [ '#1', '#2', '#3', '#4' ] + sarray = [ string_type('#1'), string_type('#2'), string_type('#3'), string_type('#4') ] + work_list = stringlist_type( carray ) + call check( work_list == carray, "test_constructor:& + & test_case 2 work_list == carray" ) + call check( work_list == sarray, "test_constructor:& + & test_case 2 work_list == sarray" ) + + write (*,*) "test_constructor: Starting test case 3!" + work_list = stringlist_type( sarray ) + call check( work_list == carray, "test_constructor:& + & test_case 3 work_list == carray" ) + call check( work_list == sarray, "test_constructor:& + & test_case 3 work_list == sarray" ) + + end subroutine test_constructor + ! compares input stringlist 'list' with an array of consecutive integers ! array is 'first' inclusive and 'last' exclusive subroutine compare_list(list, first, last, call_number) @@ -379,5 +411,6 @@ program tester call test_insert_at_string_3 call test_insert_at_array call test_insert_at_list + call test_constructor end program tester From bca711f9b870c2ab9dc086214ae3ec006f2122bb Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Mon, 16 Aug 2021 22:03:30 +0530 Subject: [PATCH 29/40] added documentation for clear, constructor and fidx/bidx --- doc/specs/stdlib_stringlist.md | 186 +++++++++++++++++++++++++++++++-- src/stdlib_stringlist.f90 | 20 ++-- 2 files changed, 185 insertions(+), 21 deletions(-) diff --git a/doc/specs/stdlib_stringlist.md b/doc/specs/stdlib_stringlist.md index 78fe21260..3dd11d1f4 100644 --- a/doc/specs/stdlib_stringlist.md +++ b/doc/specs/stdlib_stringlist.md @@ -37,12 +37,126 @@ An instance is independent of the stringlist it is used with and hence, an index Experimental + +### fidx/bidx + +#### Description + +`fidx`: Returns an instance which represents forward index `idx`. +`bidx`: Returns an instance which represents backward index `idx`. + +#### Syntax + +For fidx: `res = [[stdlib_stringlist(module):fidx()]] (idx)` +For bidx: `res = [[stdlib_stringlist(module):bidx()]] (idx)` + +#### Status + +Experimental. + +#### Class + +Pure function. + +#### Argument + +- `idx`: integer. + This argument is intent(in). + +#### Result value + +The result is of type `stringlist_index_type`. + +#### Example + +```fortran +program demo_fidx_bidx + use stdlib_stringlist, only: stringlist_type, stringlist_index_type, fidx, bidx + implicit none + + type(stringlist_type) :: stringlist + type(stringlist_index_type) :: index + + index = fidx(1) + + !> inserting 2 elements to the stringlist + call stringlist%insert_at( fidx(1), "Element No. one" ) + call stringlist%insert_at( index, "Element No. two" ) + ! stringlist <-- {"Element No. two", "Element No. one"} + + index = bidx(3) + + !> inserting 2 elements to the stringlist + call stringlist%insert_at( bidx(1), "Element No. three" ) + call stringlist%insert_at( index, "Element No. four" ) + ! stringlist <-- {"Element No. two", "Element No. four", + "Element No. one", "Element No. three"} + +end program demo_fidx_bidx +``` + + +### Constructor for stringlist + +#### Description + +No arguments given: Initializes an empty stringlist(a list containing no elements in it). + +With argument: Initializes a stringlist equivalent to the input array `array` i.e. a stringlist containing all elements of the input array `array` in the same order. + +#### Syntax + +No arguments given: `res = [[stdlib_stringlist(module):stringlist_type(interface)]] ()` +With argument: `res = [[stdlib_stringlist(module):stringlist_type(interface)]] (array)` + +#### Status + +Experimental + +#### Class + +Pure function. + +#### Argument + +No arguments. + +With argument: - `array`: array of Character scalar or array of [[stdlib_string_type(module):string_type(type)]]. + This argument is intent(in). + +#### Result value + +The result is an instance of type `stringlist_type`. + +#### Example + +```fortran +program demo_constructor + use stdlib_stringlist, only: stringlist_type + use stdlib_string_type, only: string_type + implicit none + + type(stringlist_type) :: stringlist + + stringlist = stringlist_type() + ! stringlist <-- { } (empty stringlist) + + stringlist = stringlist_type(["#1", "#2", "#3"]) + ! stringlist <-- {"#1", "#2", "#3"} + + stringlist = stringlist_type([string_type("#1"), string_type("#2")]) + ! stringlist <-- {"#1", "#2"} + +end program demo_constructor +``` + + ### insert_at #### Description -Inserts the string `string` at the index `idx` such that after insertion is done the newly added element is at index `idx`. +Inserts the string `string` _AT_ the index `idx`, so that the newly added element is present at index `idx` after insertion. Inserting an element _AT_ index beyond `length + 1` inserts the element _AT_ `list_tail`, and likewise inserting _AT_ a non-positive index inserts the element _AT_ `list_head`. #### Syntax @@ -72,7 +186,7 @@ No result. ```fortran program demo_insert_at - use stdlib_stringlist, only: stringlist_type, insert_at, stringlist_index_type, fidx, bidx + use stdlib_stringlist, only: stringlist_type, stringlist_index_type, fidx, bidx use stdlib_string_type, only: string_type implicit none @@ -102,7 +216,7 @@ end program demo_insert_at #### Description -Returns the string present currently at the index `idx` in the given stringlist. If `idx` is out of bounds an empty string is returned. +Returns the string present currently at the index `idx` in a stringlist. If index `idx` is out of bounds, then an empty string is returned. #### Syntax @@ -129,14 +243,14 @@ The result is a string of type `string_type`. ```fortran program demo_get - use stdlib_stringlist, only: stringlist_type, insert_at, fidx, get + use stdlib_stringlist, only: stringlist_type, fidx, bidx use stdlib_string_type, only: string_type implicit none type(stringlist_type) :: stringlist type(string_type) :: output - !> adding 4 elements to the stringlist + !> inserting 4 elements to the stringlist call stringlist%insert_at( fidx(1), "Element No. one" ) call stringlist%insert_at( fidx(1), "Element No. two" ) call stringlist%insert_at( fidx(1), "Element No. three" ) @@ -164,7 +278,7 @@ end program demo_get #### Description -Returns the number of elements present in the stringlist. +Returns the number of elements present currently in the stringlist. #### Syntax @@ -190,7 +304,7 @@ The result is of type `integer`. ```fortran program demo_len - use stdlib_stringlist, only: stringlist_type, insert_at, bidx, len + use stdlib_stringlist, only: stringlist_type, bidx implicit none type(stringlist_type) :: stringlist @@ -199,13 +313,65 @@ program demo_len output = stringlist%len() ! output <-- 0 - !> adding 2 elements to the stringlist + !> inserting 2 elements to the stringlist call stringlist%insert_at( bidx(1), "Element No. one" ) call stringlist%insert_at( bidx(1), "Element No. two" ) ! stringlist <-- {"Element No. one", "Element No. two"} - output = stringlist%len() - ! output <-- 2 + print'(a)', stringlist%len() + ! 2 end program demo_len ``` + + + +### clear + +#### Description + +Removes all elements from a stringlist. + +#### Syntax + +`call [[stdlib_stringlist(module):stringlist_type(type)]]%[[stdlib_stringlist(module):clear()]] ()` + +#### Status + +Experimental. + +#### Class + +Pure subroutine. + +#### Argument + +No arguments. + +#### Result value + +No result. + +#### Example + +```fortran +program demo_clear + use stdlib_stringlist, only: stringlist_type, fidx + implicit none + + type(stringlist_type) :: stringlist + + !> inserting 2 elements to the stringlist + call stringlist%insert_at( fidx(1), "Element No. one" ) + call stringlist%insert_at( fidx(1), "Element No. two" ) + ! stringlist <-- {"Element No. two", "Element No. one"} + + call stringlist%clear() + ! stringlist <-- { } (empty stringlist) + + !> inserting 1 element to the stringlist + call stringlist%insert_at( fidx(1), "Element No. one" ) + ! stringlist <-- {"Element No. one"} + +end program demo_clear +``` \ No newline at end of file diff --git a/src/stdlib_stringlist.f90 b/src/stdlib_stringlist.f90 index d8ed0a084..0ee7b4dd4 100644 --- a/src/stdlib_stringlist.f90 +++ b/src/stdlib_stringlist.f90 @@ -3,7 +3,7 @@ ! The strings may have arbitrary lengths, not necessarily the same ! ! insert AT: Inserts an element BEFORE the element present currently at the asked index -! for forward indexes, otherwise +! for forward indexes ! Inserts an element AFTER the element present currently at the asked index ! for backward indexes ! In other words, after insertion the element will be present at the asked index @@ -17,7 +17,6 @@ module stdlib_stringlist use stdlib_string_type, only: string_type, operator(/=) !, move use stdlib_math, only: clip - ! use stdlib_optval, only: optval implicit none private @@ -163,14 +162,14 @@ end function new_stringlist !> Constructor to convert chararray to stringlist !> Returns a new instance of type stringlist - pure function new_stringlist_carray( carray ) - character(len=*), dimension(:), intent(in) :: carray + pure function new_stringlist_carray( array ) + character(len=*), dimension(:), intent(in) :: array type(stringlist_type) :: new_stringlist_carray - type(string_type), dimension( size(carray) ) :: sarray + type(string_type), dimension( size(array) ) :: sarray integer :: i - do i = 1, size(carray) - sarray(i) = string_type( carray(i) ) + do i = 1, size(array) + sarray(i) = string_type( array(i) ) end do new_stringlist_carray = stringlist_type( sarray ) @@ -179,11 +178,11 @@ end function new_stringlist_carray !> Constructor to convert stringarray to stringlist !> Returns a new instance of type stringlist - pure function new_stringlist_sarray( sarray ) - type(string_type), dimension(:), intent(in) :: sarray + pure function new_stringlist_sarray( array ) + type(string_type), dimension(:), intent(in) :: array type(stringlist_type) :: new_stringlist_sarray - new_stringlist_sarray = stringlist_type( size(sarray), sarray ) + new_stringlist_sarray = stringlist_type( size(array), array ) end function new_stringlist_sarray @@ -612,7 +611,6 @@ subroutine insert_before_empty_positions( list, idxn, positions ) if (positions > 0) then idxn = clip( idxn, 1, list%len() + 1 ) - ! Matlab's infinitely expandable list (Ivan's comment)?? old_len = list%len() new_len = old_len + positions From 38052c2054b072d62da7f027c486b5128a97b914 Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Mon, 16 Aug 2021 22:24:05 +0530 Subject: [PATCH 30/40] corrected some bugs in documentation, added stringlist to index.md --- doc/specs/index.md | 1 + doc/specs/stdlib_stringlist.md | 16 +++++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/doc/specs/index.md b/doc/specs/index.md index cc804bd31..8c333e806 100644 --- a/doc/specs/index.md +++ b/doc/specs/index.md @@ -26,6 +26,7 @@ This is and index/directory of the specifications (specs) for each new module/fe - [stats_distribution_PRNG](./stdlib_stats_distribution_PRNG.html) - Probability Distributions random number generator - [string\_type](./stdlib_string_type.html) - Basic string support - [strings](./stdlib_strings.html) - String handling and manipulation routines + - [stringlist](./stdlib_stringlist.html) - 1-Dimensional list of strings ## Released/Stable Features & Modules diff --git a/doc/specs/stdlib_stringlist.md b/doc/specs/stdlib_stringlist.md index 3dd11d1f4..dffa3afe8 100644 --- a/doc/specs/stdlib_stringlist.md +++ b/doc/specs/stdlib_stringlist.md @@ -47,8 +47,8 @@ Experimental #### Syntax -For fidx: `res = [[stdlib_stringlist(module):fidx()]] (idx)` -For bidx: `res = [[stdlib_stringlist(module):bidx()]] (idx)` +For fidx: `res = [[stdlib_stringlist(module):fidx()]] (idx)`. +For bidx: `res = [[stdlib_stringlist(module):bidx()]] (idx)`. #### Status @@ -106,8 +106,9 @@ With argument: Initializes a stringlist equivalent to the input array `array` i. #### Syntax -No arguments given: `res = [[stdlib_stringlist(module):stringlist_type(interface)]] ()` -With argument: `res = [[stdlib_stringlist(module):stringlist_type(interface)]] (array)` +- No arguments given: `res = [[stdlib_stringlist(module):stringlist_type(interface)]] ()` + +- With argument: `res = [[stdlib_stringlist(module):stringlist_type(interface)]] (array)` #### Status @@ -119,10 +120,11 @@ Pure function. #### Argument -No arguments. +1). No arguments. -With argument: - `array`: array of Character scalar or array of [[stdlib_string_type(module):string_type(type)]]. - This argument is intent(in). +2). With argument: +- `array`: array of Character scalar or array of [[stdlib_string_type(module):string_type(type)]]. +This argument is intent(in). #### Result value From 1584eeb78528423496981eb59fd920243cbb7430 Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Wed, 18 Aug 2021 00:48:45 +0530 Subject: [PATCH 31/40] removed capacity function --- src/stdlib_stringlist.f90 | 55 +++++++++------------------------------ 1 file changed, 13 insertions(+), 42 deletions(-) diff --git a/src/stdlib_stringlist.f90 b/src/stdlib_stringlist.f90 index 0ee7b4dd4..176c5f0e7 100644 --- a/src/stdlib_stringlist.f90 +++ b/src/stdlib_stringlist.f90 @@ -61,8 +61,6 @@ module stdlib_stringlist procedure, public :: len => length_list - procedure :: capacity => capacity_list - procedure :: to_future_at_idxn => convert_to_future_at_idxn procedure, public :: to_current_idxn => convert_to_current_idxn @@ -477,23 +475,6 @@ pure integer function length_list( list ) end function length_list - ! capacity: - - !> Version: experimental - !> - !> Returns the capacity of the list - !> Returns an integer - pure integer function capacity_list( list ) - !> Not a part of public API - class(stringlist_type), intent(in) :: list - - capacity_list = 0 - if ( allocated( list%stringarray ) ) then - capacity_list = size( list%stringarray ) - end if - - end function capacity_list - ! to_future_at_idxn: !> Version: experimental @@ -614,29 +595,19 @@ subroutine insert_before_empty_positions( list, idxn, positions ) old_len = list%len() new_len = old_len + positions - if ( list%capacity() < new_len ) then - - allocate( new_stringarray(new_len) ) - - do i = 1, idxn - 1 - ! TODO: can be improved by move - new_stringarray(i) = list%stringarray(i) - end do - do i = idxn, old_len - inew = i + positions - ! TODO: can be improved by move - new_stringarray(inew) = list%stringarray(i) - end do - - call move_alloc( new_stringarray, list%stringarray ) - - else - do i = old_len, idxn, -1 - inew = i + positions - ! TODO: can be improved by move - list%stringarray(inew) = list%stringarray(i) - end do - end if + allocate( new_stringarray(new_len) ) + + do i = 1, idxn - 1 + ! TODO: can be improved by move + new_stringarray(i) = list%stringarray(i) + end do + do i = idxn, old_len + inew = i + positions + ! TODO: can be improved by move + new_stringarray(inew) = list%stringarray(i) + end do + + call move_alloc( new_stringarray, list%stringarray ) list%size = new_len From fb3ddd5181abccf7c4c800b9a2e250f8f470fc80 Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Wed, 18 Aug 2021 19:32:21 +0530 Subject: [PATCH 32/40] removed size component, changed the logic of len function, modified constructor, commented test cases --- src/stdlib_stringlist.f90 | 22 +++++----------------- src/tests/stringlist/test_insert_at.f90 | 12 ++++++------ 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/src/stdlib_stringlist.f90 b/src/stdlib_stringlist.f90 index 176c5f0e7..0874f3bd8 100644 --- a/src/stdlib_stringlist.f90 +++ b/src/stdlib_stringlist.f90 @@ -51,7 +51,6 @@ module stdlib_stringlist type stringlist_type private - integer :: size = 0 type(string_type), dimension(:), allocatable :: stringarray contains @@ -98,7 +97,6 @@ module stdlib_stringlist interface stringlist_type module procedure new_stringlist module procedure new_stringlist_carray - module procedure new_stringlist_sarray end interface !> Version: experimental @@ -154,7 +152,7 @@ pure function new_stringlist() type(stringlist_type) :: new_stringlist type(string_type), dimension(0) :: sarray - new_stringlist = stringlist_type( 0, sarray ) + new_stringlist = stringlist_type( sarray ) end function new_stringlist @@ -174,16 +172,6 @@ pure function new_stringlist_carray( array ) end function new_stringlist_carray - !> Constructor to convert stringarray to stringlist - !> Returns a new instance of type stringlist - pure function new_stringlist_sarray( array ) - type(string_type), dimension(:), intent(in) :: array - type(stringlist_type) :: new_stringlist_sarray - - new_stringlist_sarray = stringlist_type( size(array), array ) - - end function new_stringlist_sarray - ! constructor for stringlist_index_type: !> Returns an instance of type 'stringlist_index_type' representing forward index 'idx' @@ -455,7 +443,6 @@ end function ineq_sarray_stringlist subroutine clear_list( list ) class(stringlist_type), intent(inout) :: list - list%size = 0 if ( allocated( list%stringarray ) ) then deallocate( list%stringarray ) end if @@ -471,7 +458,10 @@ end subroutine clear_list pure integer function length_list( list ) class(stringlist_type), intent(in) :: list - length_list = list%size + length_list = 0 + if ( allocated( list%stringarray ) ) then + length_list = size( list%stringarray ) + end if end function length_list @@ -609,8 +599,6 @@ subroutine insert_before_empty_positions( list, idxn, positions ) call move_alloc( new_stringarray, list%stringarray ) - list%size = new_len - end if end subroutine insert_before_empty_positions diff --git a/src/tests/stringlist/test_insert_at.f90 b/src/tests/stringlist/test_insert_at.f90 index 04fad623b..837b5e627 100644 --- a/src/tests/stringlist/test_insert_at.f90 +++ b/src/tests/stringlist/test_insert_at.f90 @@ -368,12 +368,12 @@ subroutine test_constructor call check( work_list == sarray, "test_constructor:& & test_case 2 work_list == sarray" ) - write (*,*) "test_constructor: Starting test case 3!" - work_list = stringlist_type( sarray ) - call check( work_list == carray, "test_constructor:& - & test_case 3 work_list == carray" ) - call check( work_list == sarray, "test_constructor:& - & test_case 3 work_list == sarray" ) + ! write (*,*) "test_constructor: Starting test case 3!" + ! work_list = stringlist_type( sarray ) + ! call check( work_list == carray, "test_constructor:& + ! & test_case 3 work_list == carray" ) + ! call check( work_list == sarray, "test_constructor:& + ! & test_case 3 work_list == sarray" ) end subroutine test_constructor From 3777c045f47535eb26b3c2df11ffcb89e9afd5c3 Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Wed, 18 Aug 2021 20:10:33 +0530 Subject: [PATCH 33/40] renamed stringlist to stringlist_type --- doc/specs/index.md | 2 +- ...tringlist.md => stdlib_stringlist_type.md} | 38 +++++++++---------- src/CMakeLists.txt | 2 +- src/Makefile.manual | 4 +- ...inglist.f90 => stdlib_stringlist_type.f90} | 18 ++++----- src/tests/stringlist/test_append_prepend.f90 | 2 +- src/tests/stringlist/test_insert_at.f90 | 2 +- 7 files changed, 34 insertions(+), 34 deletions(-) rename doc/specs/{stdlib_stringlist.md => stdlib_stringlist_type.md} (83%) rename src/{stdlib_stringlist.f90 => stdlib_stringlist_type.f90} (97%) diff --git a/doc/specs/index.md b/doc/specs/index.md index 8c333e806..01ad4be26 100644 --- a/doc/specs/index.md +++ b/doc/specs/index.md @@ -26,7 +26,7 @@ This is and index/directory of the specifications (specs) for each new module/fe - [stats_distribution_PRNG](./stdlib_stats_distribution_PRNG.html) - Probability Distributions random number generator - [string\_type](./stdlib_string_type.html) - Basic string support - [strings](./stdlib_strings.html) - String handling and manipulation routines - - [stringlist](./stdlib_stringlist.html) - 1-Dimensional list of strings + - [stringlist_type](./stdlib_stringlist_type.html) - 1-Dimensional list of strings ## Released/Stable Features & Modules diff --git a/doc/specs/stdlib_stringlist.md b/doc/specs/stdlib_stringlist_type.md similarity index 83% rename from doc/specs/stdlib_stringlist.md rename to doc/specs/stdlib_stringlist_type.md index dffa3afe8..8e6888dca 100644 --- a/doc/specs/stdlib_stringlist.md +++ b/doc/specs/stdlib_stringlist_type.md @@ -1,14 +1,14 @@ --- -title: stringlist +title: stringlist type --- -# `stdlib_stringlist` module (1-D List of Strings) +# `stdlib_stringlist_type` module (1-D List of Strings) [TOC] ## Introduction -The `stdlib_stringlist` module provides with 2 derived types to deal with list of strings. +The `stdlib_stringlist_type` module provides with 2 derived types to deal with list of strings. `stringlist_type` derived type represents a one-dimensional list of variable-length strings which is compatible with Fortran intrinsic character and `stringlist_type` derived type represents an index to access, modify the elements of a stringlist and insert strings to a stringlist. ## Derived type provided @@ -47,8 +47,8 @@ Experimental #### Syntax -For fidx: `res = [[stdlib_stringlist(module):fidx()]] (idx)`. -For bidx: `res = [[stdlib_stringlist(module):bidx()]] (idx)`. +For fidx: `res = [[stdlib_stringlist_type(module):fidx()]] (idx)`. +For bidx: `res = [[stdlib_stringlist_type(module):bidx()]] (idx)`. #### Status @@ -71,7 +71,7 @@ The result is of type `stringlist_index_type`. ```fortran program demo_fidx_bidx - use stdlib_stringlist, only: stringlist_type, stringlist_index_type, fidx, bidx + use stdlib_stringlist_type, only: stringlist_type, stringlist_index_type, fidx, bidx implicit none type(stringlist_type) :: stringlist @@ -106,9 +106,9 @@ With argument: Initializes a stringlist equivalent to the input array `array` i. #### Syntax -- No arguments given: `res = [[stdlib_stringlist(module):stringlist_type(interface)]] ()` +- No arguments given: `res = [[stdlib_stringlist_type(module):stringlist_type(interface)]] ()` -- With argument: `res = [[stdlib_stringlist(module):stringlist_type(interface)]] (array)` +- With argument: `res = [[stdlib_stringlist_type(module):stringlist_type(interface)]] (array)` #### Status @@ -134,7 +134,7 @@ The result is an instance of type `stringlist_type`. ```fortran program demo_constructor - use stdlib_stringlist, only: stringlist_type + use stdlib_stringlist_type, only: stringlist_type use stdlib_string_type, only: string_type implicit none @@ -162,7 +162,7 @@ Inserts the string `string` _AT_ the index `idx`, so that the newly added elemen #### Syntax -`call [[stdlib_stringlist(module):stringlist_type(type)]]%[[stdlib_stringlist(module):insert_at(generic)]] (idx, string)` +`call [[stdlib_stringlist_type(module):stringlist_type(type)]]%[[stdlib_stringlist_type(module):insert_at(generic)]] (idx, string)` #### Status @@ -174,7 +174,7 @@ Pure subroutine. #### Argument -- `idx`: [[stdlib_stringlist(module):stringlist_index_type(type)]]. +- `idx`: [[stdlib_stringlist_type(module):stringlist_index_type(type)]]. This argument is intent(in). - `string`: Character scalar or [[stdlib_string_type(module):string_type(type)]]. @@ -188,7 +188,7 @@ No result. ```fortran program demo_insert_at - use stdlib_stringlist, only: stringlist_type, stringlist_index_type, fidx, bidx + use stdlib_stringlist_type, only: stringlist_type, stringlist_index_type, fidx, bidx use stdlib_string_type, only: string_type implicit none @@ -222,7 +222,7 @@ Returns the string present currently at the index `idx` in a stringlist. If inde #### Syntax -`res = [[stdlib_stringlist(module):stringlist_type(type)]]%[[stdlib_stringlist(module):get(generic)]] (idx)` +`res = [[stdlib_stringlist_type(module):stringlist_type(type)]]%[[stdlib_stringlist_type(module):get(generic)]] (idx)` #### Status @@ -234,7 +234,7 @@ Pure function. #### Argument -- `idx`: [[stdlib_stringlist(module):stringlist_index_type(type)]]. +- `idx`: [[stdlib_stringlist_type(module):stringlist_index_type(type)]]. This argument is intent(in). #### Result value @@ -245,7 +245,7 @@ The result is a string of type `string_type`. ```fortran program demo_get - use stdlib_stringlist, only: stringlist_type, fidx, bidx + use stdlib_stringlist_type, only: stringlist_type, fidx, bidx use stdlib_string_type, only: string_type implicit none @@ -284,7 +284,7 @@ Returns the number of elements present currently in the stringlist. #### Syntax -`res = [[stdlib_stringlist(module):stringlist_type(type)]]%[[stdlib_stringlist(module):len()]] ()` +`res = [[stdlib_stringlist_type(module):stringlist_type(type)]]%[[stdlib_stringlist_type(module):len()]] ()` #### Status @@ -306,7 +306,7 @@ The result is of type `integer`. ```fortran program demo_len - use stdlib_stringlist, only: stringlist_type, bidx + use stdlib_stringlist_type, only: stringlist_type, bidx implicit none type(stringlist_type) :: stringlist @@ -336,7 +336,7 @@ Removes all elements from a stringlist. #### Syntax -`call [[stdlib_stringlist(module):stringlist_type(type)]]%[[stdlib_stringlist(module):clear()]] ()` +`call [[stdlib_stringlist_type(module):stringlist_type(type)]]%[[stdlib_stringlist_type(module):clear()]] ()` #### Status @@ -358,7 +358,7 @@ No result. ```fortran program demo_clear - use stdlib_stringlist, only: stringlist_type, fidx + use stdlib_stringlist_type, only: stringlist_type, fidx implicit none type(stringlist_type) :: stringlist diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f70d8b65c..7dfd25f5d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -56,7 +56,7 @@ set(SRC stdlib_specialfunctions.f90 stdlib_specialfunctions_legendre.f90 stdlib_quadrature_gauss.f90 - stdlib_stringlist.f90 + stdlib_stringlist_type.f90 ${outFiles} ) diff --git a/src/Makefile.manual b/src/Makefile.manual index 0ed4e2577..fa4460c57 100644 --- a/src/Makefile.manual +++ b/src/Makefile.manual @@ -40,7 +40,7 @@ SRC = f18estop.f90 \ stdlib_logger.f90 \ stdlib_quadrature_gauss.f90 \ stdlib_strings.f90 \ - stdlib_stringlist.f90 \ + stdlib_stringlist_type.f90 \ $(SRCGEN) LIB = libstdlib.a @@ -156,6 +156,6 @@ stdlib_math_linspace.o: \ stdlib_math_logspace.o: \ stdlib_math_linspace.o stdlib_linalg_outer_product.o: stdlib_linalg.o -stdlib_stringlist.o: stdlib_string_type.o \ +stdlib_stringlist_type.o: stdlib_string_type.o \ stdlib_math.o \ stdlib_optval.o diff --git a/src/stdlib_stringlist.f90 b/src/stdlib_stringlist_type.f90 similarity index 97% rename from src/stdlib_stringlist.f90 rename to src/stdlib_stringlist_type.f90 index 0874f3bd8..23cb7ea30 100644 --- a/src/stdlib_stringlist.f90 +++ b/src/stdlib_stringlist_type.f90 @@ -1,4 +1,4 @@ -! stdlib_stringlist.f90 -- +! stdlib_stringlist_type.f90 -- ! Module for storing and manipulating list of strings ! The strings may have arbitrary lengths, not necessarily the same ! @@ -14,7 +14,7 @@ ! Note the distinction between AT and BEFORE in the module. Care has been taken to keep it consistent ! throughout the PR ! -module stdlib_stringlist +module stdlib_stringlist_type use stdlib_string_type, only: string_type, operator(/=) !, move use stdlib_math, only: clip implicit none @@ -36,7 +36,7 @@ module stdlib_stringlist !> Version: experimental !> !> Returns an instance of type 'stringlist_index_type' representing forward index - !> [Specifications](../page/specs/stdlib_stringlist.html#fidx) + !> [Specifications](../page/specs/stdlib_stringlist_type.html#fidx) interface fidx module procedure forward_index end interface @@ -44,7 +44,7 @@ module stdlib_stringlist !> Version: experimental !> !> Returns an instance of type 'stringlist_index_type' representing backward index - !> [Specifications](../page/specs/stdlib_stringlist.html#bidx) + !> [Specifications](../page/specs/stdlib_stringlist_type.html#bidx) interface bidx module procedure backward_index end interface @@ -93,7 +93,7 @@ module stdlib_stringlist !> !> Constructor for stringlist !> Returns an instance of type stringlist_type - !> [Specifications](../page/specs/stdlib_stringlist.html#stringlist_type) + !> [Specifications](../page/specs/stdlib_stringlist_type.html#stringlist_type) interface stringlist_type module procedure new_stringlist module procedure new_stringlist_carray @@ -103,7 +103,7 @@ module stdlib_stringlist !> !> Concatenates stringlist with the input entity !> Returns a new stringlist - !> [Specifications](../page/specs/stdlib_stringlist.html#append-operator) + !> [Specifications](../page/specs/stdlib_stringlist_type.html#append-operator) interface operator(//) module procedure append_char module procedure append_string @@ -120,7 +120,7 @@ module stdlib_stringlist !> !> Compares stringlist for equality with the input entity !> Returns a logical - !> [Specifications](../page/specs/stdlib_stringlist.html#equality-operator) + !> [Specifications](../page/specs/stdlib_stringlist_type.html#equality-operator) interface operator(==) module procedure eq_stringlist module procedure eq_stringlist_carray @@ -133,7 +133,7 @@ module stdlib_stringlist !> !> Compares stringlist for inequality with the input entity !> Returns a logical - !> [Specifications](../page/specs/stdlib_stringlist.html#inequality-operator) + !> [Specifications](../page/specs/stdlib_stringlist_type.html#inequality-operator) interface operator(/=) module procedure ineq_stringlist module procedure ineq_stringlist_carray @@ -723,4 +723,4 @@ pure function get_string_idx_wrap( list, idx ) end function get_string_idx_wrap -end module stdlib_stringlist +end module stdlib_stringlist_type diff --git a/src/tests/stringlist/test_append_prepend.f90 b/src/tests/stringlist/test_append_prepend.f90 index 7334ee3c7..26f6cf135 100644 --- a/src/tests/stringlist/test_append_prepend.f90 +++ b/src/tests/stringlist/test_append_prepend.f90 @@ -2,7 +2,7 @@ module test_append_prepend use stdlib_error, only: check use stdlib_string_type, only: string_type, operator(//), operator(==) - use stdlib_stringlist, only: stringlist_type, fidx, bidx, list_head, & + use stdlib_stringlist_type, only: stringlist_type, fidx, bidx, list_head, & & list_tail, operator(//), operator(==), operator(/=) use stdlib_ascii, only: to_string implicit none diff --git a/src/tests/stringlist/test_insert_at.f90 b/src/tests/stringlist/test_insert_at.f90 index 837b5e627..b7f1cd7e5 100644 --- a/src/tests/stringlist/test_insert_at.f90 +++ b/src/tests/stringlist/test_insert_at.f90 @@ -2,7 +2,7 @@ module test_insert_at use stdlib_error, only: check use stdlib_string_type, only: string_type, operator(//), operator(==) - use stdlib_stringlist, only: stringlist_type, fidx, bidx, list_head, list_tail, operator(==) + use stdlib_stringlist_type, only: stringlist_type, fidx, bidx, list_head, list_tail, operator(==) use stdlib_ascii, only: to_string implicit none From 948d0642898594121ecb7e34b651e589c9d12355 Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Thu, 19 Aug 2021 19:10:37 +0530 Subject: [PATCH 34/40] made to_current_idxn as private --- src/stdlib_stringlist_type.f90 | 2 +- src/tests/stringlist/test_insert_at.f90 | 26 ------------------------- 2 files changed, 1 insertion(+), 27 deletions(-) diff --git a/src/stdlib_stringlist_type.f90 b/src/stdlib_stringlist_type.f90 index 23cb7ea30..5ddc0e6ff 100644 --- a/src/stdlib_stringlist_type.f90 +++ b/src/stdlib_stringlist_type.f90 @@ -62,7 +62,7 @@ module stdlib_stringlist_type procedure :: to_future_at_idxn => convert_to_future_at_idxn - procedure, public :: to_current_idxn => convert_to_current_idxn + procedure :: to_current_idxn => convert_to_current_idxn procedure :: insert_at_char_idx => insert_at_char_idx_wrap procedure :: insert_at_string_idx => insert_at_string_idx_wrap diff --git a/src/tests/stringlist/test_insert_at.f90 b/src/tests/stringlist/test_insert_at.f90 index b7f1cd7e5..b29681963 100644 --- a/src/tests/stringlist/test_insert_at.f90 +++ b/src/tests/stringlist/test_insert_at.f90 @@ -17,8 +17,6 @@ subroutine test_insert_at_string_1 work_list = stringlist_type() call check( work_list%len() == 0, "test_insert_at_string_1: constructor" ) - call check( work_list%to_current_idxn( list_tail ) == 0, "test_insert_at_string_1: list_tail == 0") - call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_string_1: list_head == 1") write (*,*) "test_insert_at_string_1: Starting test case 1!" current_length = 0 @@ -36,10 +34,6 @@ subroutine test_insert_at_string_1 call check( work_list%get( list_tail ) == to_string(first), "test_insert_at_string_1: get& & list_tail " // string ) - call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_string_1:& - & to_current_idxn( list_head ) " // to_string( current_length ) ) - call check( work_list%to_current_idxn( list_tail ) == current_length, "test_insert_at_string_1:& - & to_current_idxn( list_tail ) " // to_string( current_length ) ) call check( work_list%len() == current_length, "test_insert_at_string_1: length check "& & // to_string( current_length ) ) @@ -67,10 +61,6 @@ subroutine test_insert_at_string_1 call check( work_list%get( list_head ) == to_string(first), "test_insert_at_string_1: get& & list_head " // string ) - call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_string_1:& - & to_current_idxn( list_head ) " // to_string( current_length ) ) - call check( work_list%to_current_idxn( list_tail ) == current_length, "test_insert_at_string_1:& - & to_current_idxn( list_tail ) " // to_string( current_length ) ) call check( work_list%len() == current_length, "test_insert_at_string_1: length check "& & // to_string( current_length ) ) @@ -109,10 +99,6 @@ subroutine test_insert_at_string_2 call check( work_list%get( list_tail ) == string, "test_insert_at_string_2: get& & list_tail " // string ) - call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_string_2:& - & to_current_idxn( list_head ) " // to_string( current_length ) ) - call check( work_list%to_current_idxn( list_tail ) == current_length, "test_insert_at_string_2:& - & to_current_idxn( list_tail ) " // to_string( current_length ) ) call check( work_list%len() == current_length, "test_insert_at_string_2: length check "& & // to_string( current_length ) ) @@ -138,10 +124,6 @@ subroutine test_insert_at_string_2 call check( work_list%get( list_tail ) == to_string(last), "test_insert_at_string_2: get& & list_tail " // string ) - call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_string_2:& - & to_current_idxn( list_head ) " // to_string( current_length ) ) - call check( work_list%to_current_idxn( list_tail ) == current_length, "test_insert_at_string_2:& - & to_current_idxn( list_tail ) " // to_string( current_length ) ) call check( work_list%len() == current_length, "test_insert_at_string_2: length check "& & // to_string( current_length ) ) @@ -180,10 +162,6 @@ subroutine test_insert_at_string_3 call check( work_list%get( list_head ) == string, "test_insert_at_string_3: get& & list_head " // string ) - call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_string_3:& - & to_current_idxn( list_head ) " // to_string( current_length ) ) - call check( work_list%to_current_idxn( list_tail ) == current_length, "test_insert_at_string_3:& - & to_current_idxn( list_tail ) " // to_string( current_length ) ) call check( work_list%len() == current_length, "test_insert_at_string_3: length check "& & // to_string( current_length ) ) @@ -209,10 +187,6 @@ subroutine test_insert_at_string_3 call check( work_list%get( list_head ) == to_string(last), "test_insert_at_string_3: get& & list_head " // string ) - call check( work_list%to_current_idxn( list_head ) == 1, "test_insert_at_string_3:& - & to_current_idxn( list_head ) " // to_string( current_length ) ) - call check( work_list%to_current_idxn( list_tail ) == current_length, "test_insert_at_string_3:& - & to_current_idxn( list_tail ) " // to_string( current_length ) ) call check( work_list%len() == current_length, "test_insert_at_string_3: length check "& & // to_string( current_length ) ) From f0a668c7e7781b70115da5a50b4a816ad5cd6d47 Mon Sep 17 00:00:00 2001 From: Aman Godara <34789087+Aman-Godara@users.noreply.github.com> Date: Fri, 20 Aug 2021 00:34:58 +0530 Subject: [PATCH 35/40] Apply suggestions from code review Co-authored-by: Jeremie Vandenplas --- doc/specs/stdlib_stringlist_type.md | 31 ++++++++++++----------------- src/stdlib_stringlist_type.f90 | 2 +- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/doc/specs/stdlib_stringlist_type.md b/doc/specs/stdlib_stringlist_type.md index 8e6888dca..a2c47da45 100644 --- a/doc/specs/stdlib_stringlist_type.md +++ b/doc/specs/stdlib_stringlist_type.md @@ -2,16 +2,16 @@ title: stringlist type --- -# `stdlib_stringlist_type` module (1-D List of Strings) +# `stdlib_stringlist_type` module (1-D List of strings) [TOC] ## Introduction -The `stdlib_stringlist_type` module provides with 2 derived types to deal with list of strings. -`stringlist_type` derived type represents a one-dimensional list of variable-length strings which is compatible with Fortran intrinsic character and `stringlist_type` derived type represents an index to access, modify the elements of a stringlist and insert strings to a stringlist. +The `stdlib_stringlist_type` module provides with 2 derived types to deal with lists of strings. +`stringlist_type` derived type represents a one-dimensional list of variable-length strings which is compatible with Fortran intrinsic character and `stringlist_index_type` derived type represents an index to access, modify the elements of a stringlist and insert strings to a stringlist. -## Derived type provided +## Derived types provided ### `stringlist_type` derived type @@ -30,7 +30,7 @@ Experimental An instance of the derived type `stringlist_index_type` represents either a forward index OR a backward index. The internal representation is implementation dependent and is not visible to the user of the module. `list_head` and `list_tail` are 2 special instances of this type representing the head and the tail of a stringlist respectively. -An instance is independent of the stringlist it is used with and hence, an index can be used with multiple stringlists in the same program. +An instance is independent of the `stringlist_type` it is used with and hence, an index can be used with multiple stringlists in the same program. #### Status @@ -60,8 +60,8 @@ Pure function. #### Argument -- `idx`: integer. - This argument is intent(in). +- `idx`: Shall be of kind `integer`. + This argument is `intent(in)`. #### Result value @@ -96,7 +96,7 @@ end program demo_fidx_bidx ``` -### Constructor for stringlist +### Constructor for `stringlist_type` #### Description @@ -106,9 +106,7 @@ With argument: Initializes a stringlist equivalent to the input array `array` i. #### Syntax -- No arguments given: `res = [[stdlib_stringlist_type(module):stringlist_type(interface)]] ()` - -- With argument: `res = [[stdlib_stringlist_type(module):stringlist_type(interface)]] (array)` +`res = [[stdlib_stringlist_type(module):stringlist_type(interface)]] ([array])` #### Status @@ -120,11 +118,8 @@ Pure function. #### Argument -1). No arguments. - -2). With argument: -- `array`: array of Character scalar or array of [[stdlib_string_type(module):string_type(type)]]. -This argument is intent(in). +- `array`: Shall be an array of `character` scalar or array of [[stdlib_string_type(module):string_type(type)]]. +This argument is `intent(in)` and `optional`. #### Result value @@ -175,10 +170,10 @@ Pure subroutine. #### Argument - `idx`: [[stdlib_stringlist_type(module):stringlist_index_type(type)]]. - This argument is intent(in). + This argument is `intent(in)`. - `string`: Character scalar or [[stdlib_string_type(module):string_type(type)]]. - This argument is intent(in). + This argument is `intent(in)`. #### Result value diff --git a/src/stdlib_stringlist_type.f90 b/src/stdlib_stringlist_type.f90 index 5ddc0e6ff..551ac48bf 100644 --- a/src/stdlib_stringlist_type.f90 +++ b/src/stdlib_stringlist_type.f90 @@ -15,7 +15,7 @@ ! throughout the PR ! module stdlib_stringlist_type - use stdlib_string_type, only: string_type, operator(/=) !, move + use stdlib_string_type, only: string_type, operator(/=) use stdlib_math, only: clip implicit none private From 4b69e3dd6fd473c532c1e47a977e156ccd52ec7b Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Fri, 20 Aug 2021 19:45:24 +0530 Subject: [PATCH 36/40] added constructor for string array and its test cases --- src/stdlib_stringlist_type.f90 | 15 ++++++++++++--- src/tests/stringlist/test_insert_at.f90 | 12 ++++++------ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/stdlib_stringlist_type.f90 b/src/stdlib_stringlist_type.f90 index 551ac48bf..9190d0041 100644 --- a/src/stdlib_stringlist_type.f90 +++ b/src/stdlib_stringlist_type.f90 @@ -97,6 +97,7 @@ module stdlib_stringlist_type interface stringlist_type module procedure new_stringlist module procedure new_stringlist_carray + module procedure new_stringlist_sarray end interface !> Version: experimental @@ -150,9 +151,6 @@ module stdlib_stringlist_type !> Returns a new instance of type stringlist pure function new_stringlist() type(stringlist_type) :: new_stringlist - type(string_type), dimension(0) :: sarray - - new_stringlist = stringlist_type( sarray ) end function new_stringlist @@ -172,6 +170,17 @@ pure function new_stringlist_carray( array ) end function new_stringlist_carray + !> Constructor to convert stringarray to stringlist + !> Returns a new instance of type stringlist + pure function new_stringlist_sarray( array ) + type(string_type), dimension(:), intent(in) :: array + type(stringlist_type) :: new_stringlist_sarray + + new_stringlist_sarray = stringlist_type() + new_stringlist_sarray%stringarray = array + + end function new_stringlist_sarray + ! constructor for stringlist_index_type: !> Returns an instance of type 'stringlist_index_type' representing forward index 'idx' diff --git a/src/tests/stringlist/test_insert_at.f90 b/src/tests/stringlist/test_insert_at.f90 index b29681963..202c62d61 100644 --- a/src/tests/stringlist/test_insert_at.f90 +++ b/src/tests/stringlist/test_insert_at.f90 @@ -342,12 +342,12 @@ subroutine test_constructor call check( work_list == sarray, "test_constructor:& & test_case 2 work_list == sarray" ) - ! write (*,*) "test_constructor: Starting test case 3!" - ! work_list = stringlist_type( sarray ) - ! call check( work_list == carray, "test_constructor:& - ! & test_case 3 work_list == carray" ) - ! call check( work_list == sarray, "test_constructor:& - ! & test_case 3 work_list == sarray" ) + write (*,*) "test_constructor: Starting test case 3!" + work_list = stringlist_type( sarray ) + call check( work_list == carray, "test_constructor:& + & test_case 3 work_list == carray" ) + call check( work_list == sarray, "test_constructor:& + & test_case 3 work_list == sarray" ) end subroutine test_constructor From 2c3bcdb8879e107bdf0861934b18ef150be33718 Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Fri, 20 Aug 2021 19:54:38 +0530 Subject: [PATCH 37/40] corrected some mistakes in the documentation --- doc/specs/stdlib_stringlist_type.md | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/doc/specs/stdlib_stringlist_type.md b/doc/specs/stdlib_stringlist_type.md index a2c47da45..d9187abbe 100644 --- a/doc/specs/stdlib_stringlist_type.md +++ b/doc/specs/stdlib_stringlist_type.md @@ -71,26 +71,16 @@ The result is of type `stringlist_index_type`. ```fortran program demo_fidx_bidx - use stdlib_stringlist_type, only: stringlist_type, stringlist_index_type, fidx, bidx + use stdlib_stringlist_type, only: stringlist_index_type, fidx, bidx implicit none - type(stringlist_type) :: stringlist type(stringlist_index_type) :: index index = fidx(1) - - !> inserting 2 elements to the stringlist - call stringlist%insert_at( fidx(1), "Element No. one" ) - call stringlist%insert_at( index, "Element No. two" ) - ! stringlist <-- {"Element No. two", "Element No. one"} + ! forward index 1 index = bidx(3) - - !> inserting 2 elements to the stringlist - call stringlist%insert_at( bidx(1), "Element No. three" ) - call stringlist%insert_at( index, "Element No. four" ) - ! stringlist <-- {"Element No. two", "Element No. four", - "Element No. one", "Element No. three"} + ! backward index 3 end program demo_fidx_bidx ``` @@ -175,10 +165,6 @@ Pure subroutine. - `string`: Character scalar or [[stdlib_string_type(module):string_type(type)]]. This argument is `intent(in)`. -#### Result value - -No result. - #### Example ```fortran @@ -230,7 +216,7 @@ Pure function. #### Argument - `idx`: [[stdlib_stringlist_type(module):stringlist_index_type(type)]]. - This argument is intent(in). + This argument is `intent(in)`. #### Result value @@ -345,10 +331,6 @@ Pure subroutine. No arguments. -#### Result value - -No result. - #### Example ```fortran From 9a0a33a96c75380ac8dbba9e33469193563671ae Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Fri, 20 Aug 2021 21:28:37 +0530 Subject: [PATCH 38/40] added documentation for operators //, == and /= --- doc/specs/stdlib_stringlist_type.md | 210 ++++++++++++++++++++++++++- src/stdlib_stringlist_type.f90 | 216 ++++++++++++++-------------- 2 files changed, 316 insertions(+), 110 deletions(-) diff --git a/doc/specs/stdlib_stringlist_type.md b/doc/specs/stdlib_stringlist_type.md index d9187abbe..be7fe152b 100644 --- a/doc/specs/stdlib_stringlist_type.md +++ b/doc/specs/stdlib_stringlist_type.md @@ -108,8 +108,8 @@ Pure function. #### Argument -- `array`: Shall be an array of `character` scalar or array of [[stdlib_string_type(module):string_type(type)]]. -This argument is `intent(in)` and `optional`. +- `array`: Shall be an array of `character` scalar or array of [[stdlib_string_type(module):string_type(type)]]. + This argument is `intent(in)` and `optional`. #### Result value @@ -353,4 +353,210 @@ program demo_clear ! stringlist <-- {"Element No. one"} end program demo_clear +``` + + + +### Comparison operator equal + +#### Description + +Compares left hand side (lhs) with right hand side (rhs) for equality. + +#### Syntax + +`res = lhs == rhs` + +`res = lhs .eq. rhs` + +#### Status + +Experimental. + +#### Class + +Pure function, `operator(==)` and `operator(.eq.)`. + +#### Argument + +- `lhs`: Shall be an array of `character` scalar or of [[stdlib_string_type(module):string_type(type)]] OR +a [[stdlib_stringlist_type(module):stringlist_type(type)]]. + This argument is `intent(in)`. + +- `rhs`: Shall be an array of `character` scalar or of [[stdlib_string_type(module):string_type(type)]] OR +a [[stdlib_stringlist_type(module):stringlist_type(type)]]. + This argument is `intent(in)`. + +#### Result value + +The result is a default logical scalar value. + +#### Example + +```fortran +program demo_equality_operator + use stdlib_stringlist_type, only: stringlist_type, fidx, list_head, operator(==) + use stdlib_string_type, only: string_type + implicit none + + type(stringlist_type) :: stringlist + type(string_type), allocatable :: stringarray(:) + logical :: res + + !> inserting 4 elements to the stringlist + call stringlist%insert_at( fidx(1), "#1" ) + call stringlist%insert_at( list_head, "#2" ) + call stringlist%insert_at( fidx(1), "#3" ) + call stringlist%insert_at( list_head, "#4" ) + ! stringlist <-- {"#4", "#3", "#2", "#1"} + + !> creating an array of 4 string_type elements + stringarray = [string_type("#4"), string_type("#3"), string_type("#2"), string_type("#1")] + + res = ( stringarray == stringlist ) + ! res <-- .true. + + res = ( stringlist == ["#4", "#3", "#2", "#1"] ) + ! res <-- .true. + + print'(a)', stringlist == ["#4", "#3", "#1"] + ! .false. + +end program demo_equality_operator +``` + + + +### Comparison operator not equal + +#### Description + +Compares left hand side (lhs) with right hand side (rhs) for inequality. + +#### Syntax + +`res = lhs /= rhs` + +`res = lhs .ne. rhs` + +#### Status + +Experimental. + +#### Class + +Pure function, `operator(/=)` and `operator(.ne.)`. + +#### Argument + +- `lhs`: Shall be an array of `character` scalar or of [[stdlib_string_type(module):string_type(type)]] OR +a [[stdlib_stringlist_type(module):stringlist_type(type)]]. + This argument is `intent(in)`. + +- `rhs`: Shall be an array of `character` scalar or of [[stdlib_string_type(module):string_type(type)]] OR +a [[stdlib_stringlist_type(module):stringlist_type(type)]]. + This argument is `intent(in)`. + +#### Result value + +The result is a default logical scalar value. + +#### Example + +```fortran +program demo_inequality_operator + use stdlib_stringlist_type, only: stringlist_type, bidx, list_tail, operator(/=) + use stdlib_string_type, only: string_type + implicit none + + type(stringlist_type) :: stringlist + type(string_type), allocatable :: stringarray(:) + logical :: res + + !> inserting 4 elements to the stringlist + call stringlist%insert_at( bidx(1), "#1" ) + call stringlist%insert_at( list_tail, "#2" ) + call stringlist%insert_at( bidx(1), "#3" ) + call stringlist%insert_at( list_tail, "#4" ) + ! stringlist <-- {"#1", "#2", "#3", "#4"} + + !> creating an array of 4 string_type elements + stringarray = [string_type("#1"), string_type("#2"), string_type("#3"), string_type("#4")] + + res = ( stringarray /= stringlist ) + ! res <-- .false. + + res = ( stringlist /= ["#111", "#222", "#333", "#444"] ) + ! res <-- .true. + + print'(a)', stringlist /= ["#4", "#3", "#1"] + ! .true. + +end program demo_inequality_operator +``` + + + +### Concatenation operator(//) + +#### Description + +Concatenates left hand side (lhs) and right hand side (rhs). + +#### Syntax + +`res = lhs // rhs` + +#### Status + +Experimental. + +#### Class + +Pure function, `operator(//)`. + +#### Argument + +- `lhs`: Shall be a `character` scalar or [[stdlib_string_type(module):string_type(type)]] OR an array of `character` scalar or of [[stdlib_string_type(module):string_type(type)]] OR +a [[stdlib_stringlist_type(module):stringlist_type(type)]]. + This argument is `intent(in)`. + +- `rhs`: Shall be a `character` scalar or [[stdlib_string_type(module):string_type(type)]] OR an array of `character` scalar or of [[stdlib_string_type(module):string_type(type)]] OR +a [[stdlib_stringlist_type(module):stringlist_type(type)]]. + This argument is `intent(in)`. + +#### Result value + +The result is an instance of `stringlist_type`. + +#### Example + +```fortran +program demo_concatenate_operator + use stdlib_stringlist_type, only: stringlist_type, operator(//) + use stdlib_string_type, only: string_type + implicit none + + type(stringlist_type) :: first_stringlist, second_stringlist + type(string_type), allocatable :: stringarray(:) + + first_stringlist = first_stringlist // "Element No. one" + ! first_stringlist <-- {"Element No. one"} + + second_stringlist = string_type("Element No. two") // first_stringlist + ! second_stringlist <-- {Element No. two, "Element No. one"} + + !> Creating an array of 2 string_type elements + stringarray = [string_type("Element No. three"), string_type("Element No. four")] + + second_stringlist = first_stringlist // stringarray + ! second_stringlist <-- {"Element No. one", "Element No. three", "Element No. four"} + + second_stringlist = ["#1", "#2"] // second_stringlist + ! second_stringlist <-- {"#1", "#2", "Element No. one", "Element No. three", "Element No. four"} + + first_stringlist = first_stringlist // second_stringlist + ! first_stringlist <-- {"Element No. one", "#1", "#2", "Element No. one", "Element No. three", "Element No. four"} + +end program demo_concatenate_operator ``` \ No newline at end of file diff --git a/src/stdlib_stringlist_type.f90 b/src/stdlib_stringlist_type.f90 index 9190d0041..78cfb69d3 100644 --- a/src/stdlib_stringlist_type.f90 +++ b/src/stdlib_stringlist_type.f90 @@ -203,126 +203,126 @@ end function backward_index ! concatenation operator: - !> Appends character scalar 'string' to the stringlist 'list' + !> Appends character scalar 'rhs' to the stringlist 'list' !> Returns a new stringlist - function append_char( list, string ) - type(stringlist_type), intent(in) :: list - character(len=*), intent(in) :: string + function append_char( lhs, rhs ) + type(stringlist_type), intent(in) :: lhs + character(len=*), intent(in) :: rhs type(stringlist_type) :: append_char - append_char = list // string_type( string ) + append_char = lhs // string_type( rhs ) end function append_char - !> Appends string 'string' to the stringlist 'list' + !> Appends string 'rhs' to the stringlist 'list' !> Returns a new stringlist - function append_string( list, string ) - type(stringlist_type), intent(in) :: list - type(string_type), intent(in) :: string + function append_string( lhs, rhs ) + type(stringlist_type), intent(in) :: lhs + type(string_type), intent(in) :: rhs type(stringlist_type) :: append_string - append_string = list ! Intent: creating a full, deep copy - call append_string%insert_at( list_tail, string ) + append_string = lhs ! Intent: creating a full, deep copy + call append_string%insert_at( list_tail, rhs ) end function append_string - !> Prepends character scalar 'string' to the stringlist 'list' + !> Prepends character scalar 'lhs' to the stringlist 'rhs' !> Returns a new stringlist - function prepend_char( string, list ) - character(len=*), intent(in) :: string - type(stringlist_type), intent(in) :: list + function prepend_char( lhs, rhs ) + character(len=*), intent(in) :: lhs + type(stringlist_type), intent(in) :: rhs type(stringlist_type) :: prepend_char - prepend_char = string_type( string ) // list + prepend_char = string_type( lhs ) // rhs end function prepend_char - !> Prepends string 'string' to the stringlist 'list' + !> Prepends string 'lhs' to the stringlist 'rhs' !> Returns a new stringlist - function prepend_string( string, list ) - type(string_type), intent(in) :: string - type(stringlist_type), intent(in) :: list + function prepend_string( lhs, rhs ) + type(string_type), intent(in) :: lhs + type(stringlist_type), intent(in) :: rhs type(stringlist_type) :: prepend_string - prepend_string = list ! Intent: creating a full, deep copy - call prepend_string%insert_at( list_head, string ) + prepend_string = rhs ! Intent: creating a full, deep copy + call prepend_string%insert_at( list_head, lhs ) end function prepend_string - !> Appends stringlist 'slist' to the stringlist 'list' + !> Appends stringlist 'rhs' to the stringlist 'lhs' !> Returns a new stringlist - function append_stringlist( list, slist ) - type(stringlist_type), intent(in) :: list - type(stringlist_type), intent(in) :: slist + function append_stringlist( lhs, rhs ) + type(stringlist_type), intent(in) :: lhs + type(stringlist_type), intent(in) :: rhs type(stringlist_type) :: append_stringlist - append_stringlist = list ! Intent: creating a full, deep copy - call append_stringlist%insert_at( list_tail, slist ) + append_stringlist = lhs ! Intent: creating a full, deep copy + call append_stringlist%insert_at( list_tail, rhs ) end function append_stringlist - !> Appends chararray 'carray' to the stringlist 'list' + !> Appends chararray 'rhs' to the stringlist 'lhs' !> Returns a new stringlist - function append_carray( list, carray ) - type(stringlist_type), intent(in) :: list - character(len=*), dimension(:), intent(in) :: carray + function append_carray( lhs, rhs ) + type(stringlist_type), intent(in) :: lhs + character(len=*), dimension(:), intent(in) :: rhs type(stringlist_type) :: append_carray - append_carray = list ! Intent: creating a full, deep copy - call append_carray%insert_at( list_tail, carray ) + append_carray = lhs ! Intent: creating a full, deep copy + call append_carray%insert_at( list_tail, rhs ) end function append_carray - !> Appends stringarray 'sarray' to the stringlist 'list' + !> Appends stringarray 'rhs' to the stringlist 'lhs' !> Returns a new stringlist - function append_sarray( list, sarray ) - type(stringlist_type), intent(in) :: list - type(string_type), dimension(:), intent(in) :: sarray + function append_sarray( lhs, rhs ) + type(stringlist_type), intent(in) :: lhs + type(string_type), dimension(:), intent(in) :: rhs type(stringlist_type) :: append_sarray - append_sarray = list ! Intent: creating a full, deep copy - call append_sarray%insert_at( list_tail, sarray ) + append_sarray = lhs ! Intent: creating a full, deep copy + call append_sarray%insert_at( list_tail, rhs ) end function append_sarray - !> Prepends chararray 'carray' to the stringlist 'list' + !> Prepends chararray 'lhs' to the stringlist 'rhs' !> Returns a new stringlist - function prepend_carray( carray, list ) - character(len=*), dimension(:), intent(in) :: carray - type(stringlist_type), intent(in) :: list + function prepend_carray( lhs, rhs ) + character(len=*), dimension(:), intent(in) :: lhs + type(stringlist_type), intent(in) :: rhs type(stringlist_type) :: prepend_carray - prepend_carray = list ! Intent: creating a full, deep copy - call prepend_carray%insert_at( list_head, carray ) + prepend_carray = rhs ! Intent: creating a full, deep copy + call prepend_carray%insert_at( list_head, lhs ) end function prepend_carray - !> Prepends stringarray 'sarray' to the stringlist 'list' + !> Prepends stringarray 'lhs' to the stringlist 'rhs' !> Returns a new stringlist - function prepend_sarray( sarray, list ) - type(string_type), dimension(:), intent(in) :: sarray - type(stringlist_type), intent(in) :: list + function prepend_sarray( lhs, rhs ) + type(string_type), dimension(:), intent(in) :: lhs + type(stringlist_type), intent(in) :: rhs type(stringlist_type) :: prepend_sarray - prepend_sarray = list ! Intent: creating a full, deep copy - call prepend_sarray%insert_at( list_head, sarray ) + prepend_sarray = rhs ! Intent: creating a full, deep copy + call prepend_sarray%insert_at( list_head, lhs ) end function prepend_sarray ! equality operator: - !> Compares stringlist 'list' for equality with stringlist 'slist' + !> Compares stringlist 'lhs' for equality with stringlist 'rhs' !> Returns a logical - pure logical function eq_stringlist( list, slist ) - type(stringlist_type), intent(in) :: list - type(stringlist_type), intent(in) :: slist + pure logical function eq_stringlist( lhs, rhs ) + type(stringlist_type), intent(in) :: lhs + type(stringlist_type), intent(in) :: rhs integer :: i eq_stringlist = .false. - if ( list%len() == slist%len() ) then + if ( lhs%len() == rhs%len() ) then eq_stringlist = .true. - do i = 1, list%len() - if ( list%stringarray(i) /= slist%stringarray(i) ) then + do i = 1, lhs%len() + if ( lhs%stringarray(i) /= rhs%stringarray(i) ) then eq_stringlist = .false. exit end if @@ -331,18 +331,18 @@ pure logical function eq_stringlist( list, slist ) end function eq_stringlist - !> Compares stringlist 'list' for equality with chararray 'carray' + !> Compares stringlist 'lhs' for equality with chararray 'rhs' !> Returns a logical - pure logical function eq_stringlist_carray( list, carray ) - type(stringlist_type), intent(in) :: list - character(len=*), dimension(:), intent(in) :: carray + pure logical function eq_stringlist_carray( lhs, rhs ) + type(stringlist_type), intent(in) :: lhs + character(len=*), dimension(:), intent(in) :: rhs integer :: i eq_stringlist_carray = .false. - if ( list%len() == size( carray ) ) then + if ( lhs%len() == size( rhs ) ) then eq_stringlist_carray = .true. - do i = 1, list%len() - if ( list%stringarray(i) /= carray(i) ) then + do i = 1, lhs%len() + if ( lhs%stringarray(i) /= rhs(i) ) then eq_stringlist_carray = .false. exit end if @@ -351,18 +351,18 @@ pure logical function eq_stringlist_carray( list, carray ) end function eq_stringlist_carray - !> Compares stringlist 'list' for equality with stringarray 'sarray' + !> Compares stringlist 'lhs' for equality with stringarray 'rhs' !> Returns a logical - pure logical function eq_stringlist_sarray( list, sarray ) - type(stringlist_type), intent(in) :: list - type(string_type), dimension(:), intent(in) :: sarray + pure logical function eq_stringlist_sarray( lhs, rhs ) + type(stringlist_type), intent(in) :: lhs + type(string_type), dimension(:), intent(in) :: rhs integer :: i eq_stringlist_sarray = .false. - if ( list%len() == size( sarray ) ) then + if ( lhs%len() == size( rhs ) ) then eq_stringlist_sarray = .true. - do i = 1, list%len() - if ( list%stringarray(i) /= sarray(i) ) then + do i = 1, lhs%len() + if ( lhs%stringarray(i) /= rhs(i) ) then eq_stringlist_sarray = .false. exit end if @@ -371,75 +371,75 @@ pure logical function eq_stringlist_sarray( list, sarray ) end function eq_stringlist_sarray - !> Compares stringlist 'list' for equality with chararray 'carray' + !> Compares chararray 'lhs' for equality with stringlist 'rhs' !> Returns a logical - pure logical function eq_carray_stringlist( carray, list ) - character(len=*), dimension(:), intent(in) :: carray - type(stringlist_type), intent(in) :: list + pure logical function eq_carray_stringlist( lhs, rhs ) + character(len=*), dimension(:), intent(in) :: lhs + type(stringlist_type), intent(in) :: rhs - eq_carray_stringlist = ( list == carray ) + eq_carray_stringlist = ( rhs == lhs ) end function eq_carray_stringlist - !> Compares stringlist 'list' for equality with stringarray 'sarray' + !> Compares stringarray 'lhs' for equality with stringlist 'rhs' !> Returns a logical - pure logical function eq_sarray_stringlist( sarray, list ) - type(string_type), dimension(:), intent(in) :: sarray - type(stringlist_type), intent(in) :: list + pure logical function eq_sarray_stringlist( lhs, rhs ) + type(string_type), dimension(:), intent(in) :: lhs + type(stringlist_type), intent(in) :: rhs - eq_sarray_stringlist = ( list == sarray ) + eq_sarray_stringlist = ( rhs == lhs ) end function eq_sarray_stringlist ! inequality operator: - !> Compares stringlist 'list' for inequality with stringlist 'slist' + !> Compares stringlist 'lhs' for inequality with stringlist 'rhs' !> Returns a logical - pure logical function ineq_stringlist( list, slist ) - type(stringlist_type), intent(in) :: list - type(stringlist_type), intent(in) :: slist + pure logical function ineq_stringlist( lhs, rhs ) + type(stringlist_type), intent(in) :: lhs + type(stringlist_type), intent(in) :: rhs - ineq_stringlist = .not.( list == slist ) + ineq_stringlist = .not.( lhs == rhs ) end function ineq_stringlist - !> Compares stringlist 'list' for inequality with chararray 'carray' + !> Compares stringlist 'lhs' for inequality with chararray 'rhs' !> Returns a logical - pure logical function ineq_stringlist_carray( list, carray ) - type(stringlist_type), intent(in) :: list - character(len=*), dimension(:), intent(in) :: carray + pure logical function ineq_stringlist_carray( lhs, rhs ) + type(stringlist_type), intent(in) :: lhs + character(len=*), dimension(:), intent(in) :: rhs - ineq_stringlist_carray = .not.( list == carray ) + ineq_stringlist_carray = .not.( lhs == rhs ) end function ineq_stringlist_carray - !> Compares stringlist 'list' for inequality with stringarray 'sarray' + !> Compares stringlist 'lhs' for inequality with stringarray 'rhs' !> Returns a logical - pure logical function ineq_stringlist_sarray( list, sarray ) - type(stringlist_type), intent(in) :: list - type(string_type), dimension(:), intent(in) :: sarray + pure logical function ineq_stringlist_sarray( lhs, rhs ) + type(stringlist_type), intent(in) :: lhs + type(string_type), dimension(:), intent(in) :: rhs - ineq_stringlist_sarray = .not.( list == sarray ) + ineq_stringlist_sarray = .not.( lhs == rhs ) end function ineq_stringlist_sarray - !> Compares stringlist 'list' for inequality with chararray 'carray' + !> Compares chararray 'lhs' for inequality with stringlist 'rhs' !> Returns a logical - pure logical function ineq_carray_stringlist( carray, list ) - character(len=*), dimension(:), intent(in) :: carray - type(stringlist_type), intent(in) :: list + pure logical function ineq_carray_stringlist( lhs, rhs ) + character(len=*), dimension(:), intent(in) :: lhs + type(stringlist_type), intent(in) :: rhs - ineq_carray_stringlist = .not.( carray == list) + ineq_carray_stringlist = .not.( lhs == rhs) end function ineq_carray_stringlist - !> Compares stringlist 'list' for inequality with stringarray 'sarray' + !> Compares stringarray 'lhs' for inequality with stringlist 'rhs' !> Returns a logical - pure logical function ineq_sarray_stringlist( sarray, list ) - type(string_type), dimension(:), intent(in) :: sarray - type(stringlist_type), intent(in) :: list + pure logical function ineq_sarray_stringlist( lhs, rhs ) + type(string_type), dimension(:), intent(in) :: lhs + type(stringlist_type), intent(in) :: rhs - ineq_sarray_stringlist = .not.( sarray == list ) + ineq_sarray_stringlist = .not.( lhs == rhs ) end function ineq_sarray_stringlist From 2e5e822a1e45b8e562807a450abe13f3e2dc8b24 Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Fri, 20 Aug 2021 22:59:15 +0530 Subject: [PATCH 39/40] some minor improvements in doc --- doc/specs/stdlib_stringlist_type.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/doc/specs/stdlib_stringlist_type.md b/doc/specs/stdlib_stringlist_type.md index be7fe152b..88dc6521a 100644 --- a/doc/specs/stdlib_stringlist_type.md +++ b/doc/specs/stdlib_stringlist_type.md @@ -2,23 +2,25 @@ title: stringlist type --- -# `stdlib_stringlist_type` module (1-D List of strings) +# `stdlib_stringlist_type` module (1-D list of strings) [TOC] ## Introduction The `stdlib_stringlist_type` module provides with 2 derived types to deal with lists of strings. -`stringlist_type` derived type represents a one-dimensional list of variable-length strings which is compatible with Fortran intrinsic character and `stringlist_index_type` derived type represents an index to access, modify the elements of a stringlist and insert strings to a stringlist. +`stringlist_type` derived type represents one-dimensional list of variable-length strings (also referred as one-dimensional stringlist) which is compatible with Fortran intrinsic character and `stringlist_index_type` derived type represents an index to access, modify the elements of a stringlist, insert elements to a stringlist and much more. ## Derived types provided ### `stringlist_type` derived type -The `stringlist_type` derived type represents one-dimensional list of strings. +The `stringlist_type` derived type represents one-dimensional list of strings (also referred as one-dimensional stringlist). The internal representation of the list is implementation dependent and is not visible to the user of the module. +Note: _stringlist_ is an abstract concept which is expressed through the derived type `stringlist_type`. + #### Status Experimental @@ -30,7 +32,7 @@ Experimental An instance of the derived type `stringlist_index_type` represents either a forward index OR a backward index. The internal representation is implementation dependent and is not visible to the user of the module. `list_head` and `list_tail` are 2 special instances of this type representing the head and the tail of a stringlist respectively. -An instance is independent of the `stringlist_type` it is used with and hence, an index can be used with multiple stringlists in the same program. +An index is independent of the stringlist(or `stringlist_type`) it is used with and hence, an index can be used with multiple stringlists in the same program. #### Status @@ -86,11 +88,11 @@ end program demo_fidx_bidx ``` -### Constructor for `stringlist_type` +### Constructor for `stringlist_type`(or stringlist) #### Description -No arguments given: Initializes an empty stringlist(a list containing no elements in it). +No arguments given: Initializes an empty stringlist(a stringlist containing no elements in it). With argument: Initializes a stringlist equivalent to the input array `array` i.e. a stringlist containing all elements of the input array `array` in the same order. @@ -389,7 +391,7 @@ a [[stdlib_stringlist_type(module):stringlist_type(type)]]. #### Result value -The result is a default logical scalar value. +The result is a default `logical` scalar value. #### Example @@ -459,7 +461,7 @@ a [[stdlib_stringlist_type(module):stringlist_type(type)]]. #### Result value -The result is a default logical scalar value. +The result is a default `logical` scalar value. #### Example @@ -501,7 +503,7 @@ end program demo_inequality_operator #### Description -Concatenates left hand side (lhs) and right hand side (rhs). +Returns the concatenated output of left hand side (lhs) and right hand side (rhs). #### Syntax From cea79e8abecf29f01cd85f0c9ece3708e135ed48 Mon Sep 17 00:00:00 2001 From: Aman-Godara Date: Tue, 24 Aug 2021 14:20:23 +0530 Subject: [PATCH 40/40] dependency to_string has been moved to stdlib_strings --- src/tests/stringlist/test_append_prepend.f90 | 2 +- src/tests/stringlist/test_insert_at.f90 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/stringlist/test_append_prepend.f90 b/src/tests/stringlist/test_append_prepend.f90 index 26f6cf135..9b12bec08 100644 --- a/src/tests/stringlist/test_append_prepend.f90 +++ b/src/tests/stringlist/test_append_prepend.f90 @@ -4,7 +4,7 @@ module test_append_prepend use stdlib_string_type, only: string_type, operator(//), operator(==) use stdlib_stringlist_type, only: stringlist_type, fidx, bidx, list_head, & & list_tail, operator(//), operator(==), operator(/=) - use stdlib_ascii, only: to_string + use stdlib_strings, only: to_string implicit none contains diff --git a/src/tests/stringlist/test_insert_at.f90 b/src/tests/stringlist/test_insert_at.f90 index 202c62d61..231ac0e9c 100644 --- a/src/tests/stringlist/test_insert_at.f90 +++ b/src/tests/stringlist/test_insert_at.f90 @@ -3,7 +3,7 @@ module test_insert_at use stdlib_error, only: check use stdlib_string_type, only: string_type, operator(//), operator(==) use stdlib_stringlist_type, only: stringlist_type, fidx, bidx, list_head, list_tail, operator(==) - use stdlib_ascii, only: to_string + use stdlib_strings, only: to_string implicit none contains