Skip to content

Commit 9402f91

Browse files
committed
Add ResultInt and clean up suggested Result implemenations
1 parent 3c57801 commit 9402f91

3 files changed

Lines changed: 94 additions & 8 deletions

File tree

meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ if pyprojectwheelbuild_enabled
6969
'src/example_fgen_basic/get_wavelength.f90',
7070
'src/example_fgen_basic/kind_parameters.f90',
7171
'src/example_fgen_basic/result/result.f90',
72+
'src/example_fgen_basic/result/result_int.f90',
7273
)
7374

7475
# All Python files (wrappers and otherwise)

src/example_fgen_basic/result/result.f90

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ module m_result
1212
!!
1313
!! Holds either the result or an error.
1414

15-
class(*), allocatable :: data(..)
15+
class(*), allocatable :: data_v(..)
1616
!! Data i.e. the result (if no error occurs)
1717
!!
1818
! Assumed rank array
@@ -31,9 +31,10 @@ module m_result
3131

3232
private
3333

34-
procedure, public:: build, finalise, is_error
34+
! procedure, public:: build
3535
! TODO: Think about whether build should be on the abstract class
3636
! or just on each concrete implementation
37+
procedure, public:: finalise, is_error
3738

3839
end type Result
3940

@@ -68,16 +69,33 @@ module m_result
6869
!
6970
! end subroutine build
7071

71-
subroutine finalise(self)
72+
function finalise(self) result(res)
7273
!! Finalise the instance (i.e. free/deallocate)
7374

7475
class(Result), intent(inout) :: self
7576
! Hopefully can leave without docstring (like Python)
7677

77-
deallocate(self % data)
78-
deallocate(self % error)
78+
type(ResultNone) :: res
7979

80-
end subroutine finalise
80+
if (allocated(self % data_v) .and. allocated(self % error)) then
81+
deallocate(self % data_v)
82+
deallocate(self % error)
83+
call res % build(message="Both data and error were allocated")
84+
85+
elseif (allocated(self % data_v)) then
86+
deallocate(self % data_v)
87+
! No error - no need to call res % build
88+
89+
elseif (allocated(self % error)) then
90+
deallocate(self % error)
91+
! No error - no need to call res % build
92+
93+
else
94+
call res % build(message="Neither data nor error was allocated")
95+
96+
end if
97+
98+
end function finalise
8199

82100
pure function is_error(self) result(is_err)
83101
!! Determine whether `self` contains an error or not
@@ -88,8 +106,7 @@ pure function is_error(self) result(is_err)
88106
logical :: is_err
89107
! Whether `self` is an error or not
90108

91-
is_err = self % error_v % is_error()
92-
! TODO: implement is_error on `error_v`
109+
is_err = allocated(self % error_v)
93110

94111
end function is_error
95112

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
!> Result value for integers
2+
!>
3+
!> Inspired by the excellent, MIT licensed
4+
!> https://github.com/samharrison7/fortran-error-handler
5+
module m_result_int
6+
7+
use m_error_v, only: ErrorV
8+
9+
implicit none
10+
private
11+
12+
type, extends(Result), public :: ResultInteger
13+
!! Result type that holds integer values
14+
!!
15+
!! Holds either an integer value or an error.
16+
17+
integer, allocatable :: data_v
18+
!! Data i.e. the result (if no error occurs)
19+
20+
class(ErrorV), allocatable :: error_v
21+
!! Error
22+
23+
contains
24+
25+
private
26+
27+
procedure, public:: build
28+
! `finalise` and `is_error` come from abstract base class
29+
30+
end type ResultInteger
31+
32+
interface ResultInteger
33+
!! Constructor interface - see build (TODO: figure out cross-ref syntax) for details
34+
module procedure :: constructor
35+
end interface ResultInteger
36+
37+
contains
38+
39+
subroutine build(self, res, data_v, error_v)
40+
!! Build instance
41+
42+
type(ResultInteger), intent(inout) :: self
43+
! Hopefully can leave without docstring (like Python)
44+
45+
type(ResultNone), intent(inout) :: res
46+
!! Result
47+
48+
integer, optional, intent(in) :: data_v
49+
!! Data
50+
51+
class(ErrorV), optional, intent(in) :: error_v
52+
!! Error message
53+
54+
if (present(data_v) and present(error_v)) then
55+
call res % build(message="Both data and error were provided")
56+
elseif (present(data_v)) then
57+
allocate(self % data_v, source=data_v)
58+
! No error - no need to call res % build
59+
elseif (present(error_v)) then
60+
allocate(self % error_v, source=error_v)
61+
! No error - no need to call res % build
62+
else
63+
call res % build(message="Neither data nor error were provided")
64+
end if
65+
66+
end subroutine build
67+
68+
end module m_result_int

0 commit comments

Comments
 (0)