is_real Function

private elemental function is_real(self, allow_spaces)

Arguments

Type IntentOptional AttributesName
class(string), intent(in) :: self

The string.

logical, intent(in), optional :: allow_spaces

Allow leading-trailing spaces.

Return Value logical

Result of the test.

Description

Return true if the string contains a real.

The regular expression is \s*[\+\-]?\d*(|\.?\d*([deDE][\+\-]?\d+)?)\s*. The parse algorithm is done in stages:

S0 S1 S2 S3 S4 S5 S6 S7 S8
\s* [\+\-]? \d* \.? \d* [deDE] [\+\-]? \d* \s*

Exit on stages-parsing results in:

S0 S1 S2 S3 S4 S5 S6 S7 S8


Variables

TypeVisibility AttributesNameInitial
logical, public :: allow_spaces_

Allow leading-trailing spaces, local variable.

logical, public :: has_leading_digit

Check the presence of leading digits.

integer, public :: stage

Stages counter.

integer, public :: c

Character counter.


Source Code

  elemental function is_real(self, allow_spaces)
  !---------------------------------------------------------------------------------------------------------------------------------
  !< Return true if the string contains a real.
  !<
  !< The regular expression is `\s*[\+\-]?\d*(|\.?\d*([deDE][\+\-]?\d+)?)\s*`. The parse algorithm is done in stages:
  !<
  !< | S0  | S1      | S2  | S3  | S4  | S5     | S6      | S7  | S8  |
  !< |-----|---------|-----|-----|-----|--------|---------|-----|-----|
  !< |`\s*`|`[\+\-]?`|`\d*`|`\.?`|`\d*`|`[deDE]`|`[\+\-]?`|`\d*`|`\s*`|
  !<
  !< Exit on stages-parsing results in:
  !<
  !< | S0 | S1 | S2 | S3 | S4 | S5 | S6 | S7 | S8 |
  !< |----|----|----|----|----|----|----|----|----|
  !  |  F |  F |  T |  T |  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#L614)
  !---------------------------------------------------------------------------------------------------------------------------------
  class(string), intent(in)           :: self              !< The string.
  logical,       intent(in), optional :: allow_spaces      !< Allow leading-trailing spaces.
  logical                             :: is_real           !< Result of the test.
  logical                             :: allow_spaces_     !< Allow leading-trailing spaces, local variable.
  logical                             :: has_leading_digit !< Check the presence of leading digits.
  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_real = .true.
    has_leading_digit = .false.
    do c=1, len(self%raw)
      select case(self%raw(c:c))
      case(SPACE, TAB)
        select case(stage)
        case(0, 8)
          is_real = allow_spaces_
          continue
        case(2:4, 7)
          is_real = allow_spaces_
          stage = 8
        case default
          is_real = .false.
        endselect
      case('+', '-')
        select case(stage)
        case(0)
          stage = 1
        case(5)
          stage = 6
        case default
          is_real = .false.
        endselect
      case('0':'9')
        select case(stage)
        case(0:1)
          stage = 2
          has_leading_digit = .true.
        case(3)
          stage = 4
        case(5:6)
          stage = 7
        case default
          continue
        endselect
      case('.')
        select case(stage)
        case(0:2)
          stage = 3
        case default
          is_real = .false.
        endselect
      case('e','E','d','D')
        select case(stage)
        case(2:4)
          stage = 5
        case default
          is_real = .false.
        endselect
      case default
        is_real = .false.
      endselect
      if (.not.is_real) exit
    enddo
  endif
  if (is_real) then
    select case(stage)
    case(2, 4, 7, 8)
      is_real = .true.
    case(3)
      is_real = has_leading_digit
    case default
      is_real = .false.
    endselect
  endif
  return
  !---------------------------------------------------------------------------------------------------------------------------------
  endfunction is_real