queue.tcl
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 namespace ::struct {}
00013 namespace ::struct::queue {
00014
00015 variable queues
00016
00017
00018 variable counter 0
00019
00020
00021 namespace export queue
00022 }
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 ret ::struct::queue::queue (type args) {
00036 variable queues
00037 variable counter
00038
00039 switch -exact -- [llength [info level 0]] {
00040 1 {
00041 # Missing name, generate one.
00042 incr counter
00043 set name "queue${counter}"
00044 }
00045 2 {
00046 # Standard call. New empty queue.
00047 set name [lindex $args 0]
00048 }
00049 default {
00050 # Error.
00051 return -code error \
00052 "wrong # args: should be \"queue ?name?\""
00053 }
00054 }
00055
00056 # FIRST, qualify the name.
00057 if {![string match "::*" $name]} {
00058 # Get caller's namespace; append :: if not global namespace.
00059 set ns [uplevel 1 [list namespace current]]
00060 if {"::" != $ns} {
00061 append ns "::"
00062 }
00063
00064 set name "$ns$name"
00065 }
00066 if {[llength [info commands $name]]} {
00067 return -code error \
00068 "command \"$name\" already exists, unable to create queue"
00069 }
00070
00071 # Initialize the queue as empty
00072 set queues($name) [list ]
00073
00074 # Create the command to manipulate the queue
00075 interp alias {} $name {} ::struct::queue::QueueProc $name
00076
00077 return $name
00078 }
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 ret ::struct::queue::QueueProc (type name , optional cmd ="" , type args) {
00095 # Do minimal args checks here
00096 if { [llength [info level 0]] == 2 } {
00097 error "wrong # args: should be \"$name option ?arg arg ...?\""
00098 }
00099
00100 # Split the args into command and args components
00101 set sub _$cmd
00102 if { [llength [info commands ::struct::queue::$sub]] == 0 } {
00103 set optlist [lsort [info commands ::struct::queue::_*]]
00104 set xlist {}
00105 foreach p $optlist {
00106 set p [namespace tail $p]
00107 lappend xlist [string range $p 1 end]
00108 }
00109 set optlist [linsert [join $xlist ", "] "end-1" "or"]
00110 return -code error \
00111 "bad option \"$cmd\": must be $optlist"
00112 }
00113
00114 uplevel 1 [linsert $args 0 ::struct::queue::_$cmd $name]
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 ret ::struct::queue::_clear (type name) {
00128 variable queues
00129 set queues($name) [list ]
00130 return
00131 }
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 ret ::struct::queue::_destroy (type name) {
00145 variable queues
00146 unset queues($name)
00147 interp alias {} $name {}
00148 return
00149 }
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 ret ::struct::queue::_get (type name , optional count =1) {
00164 variable queues
00165 if { $count < 1 } {
00166 error "invalid item count $count"
00167 }
00168
00169 if { $count > [llength $queues($name)] } {
00170 error "insufficient items in queue to fill request"
00171 }
00172
00173 if { $count == 1 } {
00174 # Handle this as a special case, so single item gets aren't listified
00175 set item [lindex $queues($name) 0]
00176 set queues($name) [lreplace $queues($name) 0 0]
00177 return $item
00178 }
00179
00180 # Otherwise, return a list of items
00181 set index [expr {$count - 1}]
00182 set result [lrange $queues($name) 0 $index]
00183 set queues($name) [lreplace $queues($name) 0 $index]
00184
00185 return $result
00186 }
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 ret ::struct::queue::_peek (type name , optional count =1) {
00201 variable queues
00202 if { $count < 1 } {
00203 error "invalid item count $count"
00204 }
00205
00206 if { $count > [llength $queues($name)] } {
00207 error "insufficient items in queue to fill request"
00208 }
00209
00210 if { $count == 1 } {
00211 # Handle this as a special case, so single item pops aren't listified
00212 return [lindex $queues($name) 0]
00213 }
00214
00215 # Otherwise, return a list of items
00216 set index [expr {$count - 1}]
00217 return [lrange $queues($name) 0 $index]
00218 }
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 ret ::struct::queue::_put (type name , type args) {
00232 variable queues
00233 if { [llength $args] == 0 } {
00234 error "wrong # args: should be \"$name put item ?item ...?\""
00235 }
00236 foreach item $args {
00237 lappend queues($name) $item
00238 }
00239 return
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 ret ::struct::queue::_unget (type name , type item) {
00254 variable queues
00255 if {![llength $queues($name)]} {
00256 set queues($name) [list $item]
00257 } else {
00258 set queues($name) [linsert $queues($name) 0 $item]
00259 }
00260 return
00261 }
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 ret ::struct::queue::_size (type name) {
00274 variable queues
00275 return [llength $queues($name)]
00276 }
00277
00278
00279
00280
00281 namespace ::struct {
00282
00283 namespace import -force queue::queue
00284 namespace export queue
00285 }
00286 package provide struct::queue 1.4
00287