pure subroutine split_chunked(self, tokens, chunks, sep)
!< Return a list of substring in the string, using sep as the delimiter string, chunked (memory-efficient) algorithm.
!<
!< @note Multiple subsequent separators are collapsed to one occurrence.
!<
!< @note The split is performed in chunks of `#chunks` to avoid excessive memory consumption.
!<
!<```fortran
!< type(string) :: astring
!< type(string), allocatable :: strings(:)
!< logical :: test_passed(1)
!< astring = '-1-2-3-4-5-6-7-8-'
!< call astring%split_chunked(tokens=strings, sep='-', chunks=3)
!< test_passed(1) = (strings(1)//''=='1'.and.strings(2)//''=='2'.and.strings(3)//''=='3'.and.strings(4)//''=='4'.and. &
!< strings(5)//''=='5'.and.strings(6)//''=='6'.and.strings(7)//''=='7'.and.strings(8)//''=='8')
!< print '(L1)', all(test_passed)
!<```
!=> T <<<
class(string), intent(in) :: self !< The string.
type(string), allocatable, intent(out) :: tokens(:) !< Tokens substring.
integer, intent(in) :: chunks !< Number of chunks.
character(kind=CK, len=*), intent(in), optional :: sep !< Separator.
character(kind=CK, len=:), allocatable :: sep_ !< Separator, default value.
integer :: Nt !< Number of actual tokens.
integer :: t !< Counter.
logical :: isok
if (allocated(self%raw)) then
sep_ = SPACE ; if (present(sep)) sep_ = sep
Nt = self%count(sep_)
if (self%start_with(prefix=sep_)) Nt = Nt - 1
if (self%end_with(suffix=sep_)) Nt = Nt - 1
t = 0
call self%split(tokens=tokens, sep=sep_, max_tokens=chunks)
do
t = size(tokens, dim=1)
if (t > Nt) exit
call split_last_token(tokens=tokens, max_tokens=chunks,isok=isok)
if(isok)then
else
exit
endif
enddo
t = size(tokens, dim=1)
if (tokens(t)%count(sep_) > 0) then
call split_last_token(tokens=tokens,isok=isok)
endif
endif
contains
pure subroutine split_last_token(tokens, max_tokens,isok)
!< Split last token.
type(string), allocatable, intent(inout) :: tokens(:) !< Tokens substring.
integer, intent(in), optional :: max_tokens !< Max tokens returned.
type(string), allocatable :: tokens_(:) !< Temporary tokens.
type(string), allocatable :: tokens_swap(:) !< Swap tokens.
integer :: Nt_ !< Number of last created tokens.
logical,intent(out) :: isok
isok=.true.
call tokens(t)%split(tokens=tokens_, sep=sep_, max_tokens=max_tokens)
if (allocated(tokens_)) then
Nt_ = size(tokens_, dim=1)
if (Nt_ >= 1) then
allocate(tokens_swap(1:t-1+Nt_))
tokens_swap(1:t-1) = tokens(1:t-1)
tokens_swap(t:) = tokens_(:)
call move_alloc(from=tokens_swap, to=tokens)
endif
if (Nt_ == 1) then
isok=.false.
end if
deallocate(tokens_)
endif
endsubroutine split_last_token
endsubroutine split_chunked