-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathqueues.f90
173 lines (152 loc) · 4.52 KB
/
queues.f90
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
! queues.f90 --
! Include file for defining queues with a fixed capacity
!
! See the example/test program for the way to use this
!
! Queues as implemented here are simply arrays where
! data are inserted at the end and retrieved from the
! top.
!
! $Id: queues.f90,v 1.2 2006/03/26 19:03:53 arjenmarkus Exp $
!
type QUEUE_STRUCT
logical :: full
integer :: start
integer :: end
type(QUEUE_DATA), dimension(:), pointer :: data
end type QUEUE_STRUCT
!
! Define the subroutines and functions
!
contains
! queue_create --
! Create and initialise a queue
! Arguments:
! queue Pointer to new queue
! capacity The number of data that can be stored
! Note:
! This version assumes a shallow copy is enough
! (that is, there are no pointers within the data
! to be stored)
! It also assumes the argument queue does not already
! refer to a queue. Use queue_destroy first to
! destroy an old queue.
!
! There is no check that the capacity is positive!
!
subroutine queue_create( queue, capacity )
type(QUEUE_STRUCT), pointer :: queue
integer :: capacity
integer :: allocstat
allocate( queue, STAT=allocstat)
if (allocstat /= 0) STOP "***NOT ENOUGH MEMORY***"
allocate( queue%data(1:capacity) )
queue%full = .false.
queue%start = 1
queue%end = 0
end subroutine queue_create
! queue_destroy --
! Destroy a queue
! Arguments:
! queue Pointer to the queue to be destroyed
! Note:
! This version assumes that there are no
! pointers within the data that need deallocation
!
subroutine queue_destroy( queue )
type(QUEUE_STRUCT), pointer :: queue
deallocate( queue%data )
deallocate( queue )
end subroutine queue_destroy
! queue_empty --
! Check if the queue is empty
! Arguments:
! queue Pointer to the queue
! Result:
! logical indicating if the queue is
! empty or not
!
logical function queue_empty( queue )
type(QUEUE_STRUCT), intent(in) :: queue
queue_empty = .not. queue%full .and. &
queue%end .eq. queue%start - 1
end function queue_empty
! queue_full --
! Check if the queue is full
! Arguments:
! queue Pointer to the queue
! Result:
! logical indicating if the queue is
! full or not
!
logical function queue_full( queue )
type(QUEUE_STRUCT), intent(in) :: queue
queue_full = queue%full
end function queue_full
! queue_start_data
! Return the data stored at the start,
! but leave them in
! Arguments:
! queue Queue to be examined
! Result:
! Data stored at the start
! Note:
! With an empty queue, random data
! are returned!
!
function queue_start_data( queue ) result(data)
type(QUEUE_STRUCT), intent(in) :: queue
type(QUEUE_DATA) :: data
data = queue%data(queue%start)
end function queue_start_data
! queue_retrieve_data
! Return the data stored at the top,
! and remove them from the queue
! Arguments:
! queue Queue to be examined
! Result:
! Data stored at the top, afterwards
! removed
! Note:
! With an empty queue, random data
! are returned!
!
function queue_retrieve_data( queue ) result(data)
type(QUEUE_STRUCT) :: queue
type(QUEUE_DATA) :: data
data = queue%data(queue%start)
if ( .not. queue_empty(queue) ) then
queue%start = queue%start + 1
if ( queue%start .gt. size(queue%data) ) then
queue%start = 1
endif
queue%full = .false.
endif
end function queue_retrieve_data
! queue_append_data
! Append data to the end of the queue
! Arguments:
! queue Queueu to which to add the data
! data The data to be added
! success Indicates success or not
!
subroutine queue_append_data( queue, data, success )
type(QUEUE_STRUCT) :: queue
type(QUEUE_DATA), intent(in) :: data
logical, intent(out) :: success
success = .not. queue_full( queue )
if ( success ) then
queue%end = queue%end + 1
if ( queue%end .gt. size(queue%data) ) then
queue%end = 1
endif
if ( queue%start .eq. queue%end+1 ) then
queue%full = .true.
endif
if ( queue%end .eq. size(queue%data) .and. &
queue%start .eq. 1 ) then
queue%full = .true.
endif
queue%data(queue%end) = data
endif
end subroutine queue_append_data