elemental function is_integer(self, allow_spaces)
!< Return true if the string contains an integer.
!<
!< The regular expression is `\s*[\+\-]?\d+([eE]\+?\d+)?\s*`. The parse algorithm is done in stages:
!<
!< | S0 | S1 | S2 | S3 | S4 | S5 | S6 |
!< |-----|---------|-----|------|-----|-----|-----|
!< |`\s*`|`[\+\-]?`|`\d+`|`[eE]`|`\+?`|`\d+`|`\s*`|
!<
!< Exit on stages-parsing results in:
!<
!< | S0 | S1 | S2 | S3 | S4 | S5 | S6 |
!< |----|----|----|----|----|----|----|
!< | F | F | T | F | F | T | T |
!<
!< @note This implementation is courtesy of
!< [tomedunn](https://github.com/tomedunn/fortran-string-utility-module/blob/master/src/string_utility_module.f90#L294)
!<
!<```fortran
!< type(string) :: astring
!< logical :: test_passed(6)
!< astring = ' -1212112 '
!< test_passed(1) = astring%is_integer().eqv..true.
!< astring = ' -1212112'
!< test_passed(2) = astring%is_integer(allow_spaces=.false.).eqv..false.
!< astring = '-1212112 '
!< test_passed(3) = astring%is_integer(allow_spaces=.false.).eqv..false.
!< astring = '+2e20'
!< test_passed(4) = astring%is_integer().eqv..true.
!< astring = ' -2E13 '
!< test_passed(5) = astring%is_integer().eqv..true.
!< astring = ' -2 E13 '
!< test_passed(6) = astring%is_integer().eqv..false.
!< print '(L1)', all(test_passed)
!<```
!=> T <<<
class(string), intent(in) :: self !< The string.
logical, intent(in), optional :: allow_spaces !< Allow leading-trailing spaces.
logical :: is_integer !< Result of the test.
logical :: allow_spaces_ !< Allow leading-trailing spaces, local variable.
integer :: stage !< Stages counter.
integer :: c !< Character counter.
if (allocated(self%raw)) then
allow_spaces_ = .true. ; if (present(allow_spaces)) allow_spaces_ = allow_spaces
stage = 0
is_integer = .true.
do c=1, len(self%raw)
select case(self%raw(c:c))
case(SPACE, TAB)
select case(stage)
case(0, 6)
is_integer = allow_spaces_
case(2, 5)
is_integer = allow_spaces_
stage = 6
case default
is_integer = .false.
endselect
case('-')
select case(stage)
case(0)
stage = 1
case default
is_integer = .false.
end select
case('+')
select case(stage)
case(0)
stage = 1
case(3)
stage = 4
case default
is_integer = .false.
endselect
case('0':'9')
select case(stage)
case(0:1)
stage = 2
case(3:4)
stage = 5
case default
continue
endselect
case ('e','E')
select case(stage)
case(2)
stage = 3
case default
is_integer = .false.
endselect
case default
is_integer = .false.
endselect
if (.not.is_integer) exit
enddo
endif
if (is_integer) then
select case(stage)
case(2, 5, 6)
is_integer = .true.
case default
is_integer = .false.
end select
endif
endfunction is_integer