is_integer Function

private elemental function is_integer(self, allow_spaces)

Arguments

TypeIntentOptionalAttributesName
class(string), intent(in) :: self
logical, intent(in), optional :: allow_spaces

Return Value logical


Contents

Source Code


Source Code

   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