/src/lib/storage/collection2.e
Specman e | 433 lines | 317 code | 39 blank | 77 comment | 9 complexity | 54c16a7ce3a37b92092a7af1f60616a7 MD5 | raw file
1-- This file is part of a Liberty Eiffel library. 2-- See the full copyright at the end. 3-- 4deferred class COLLECTION2[E_] 5 -- 6 -- Abstract definition of a 2 dimensional collection of elements of type E_. 7 -- 8 -- The Liberty Eiffel standard library provides two implementations of COLLECTION2: ARRAY2 and FIXED_ARRAY2. 9 -- All implementations have exactly the same behavior. Switching from one implementation to 10 -- another only change the memory used and the execution time. 11 -- 12 13insert 14 SAFE_EQUAL[E_] 15 undefine copy 16 redefine fill_tagged_out_memory, is_equal 17 end 18 19feature {ANY} -- Indexing: 20 lower1, lower2: INTEGER 21 -- Lower index bounds. 22 deferred 23 end 24 25 frozen line_minimum: INTEGER 26 -- Equivalent of `lower1'. 27 do 28 Result := lower1 29 end 30 31 frozen column_minimum: INTEGER 32 -- Equivalent of `lower2'. 33 do 34 Result := lower2 35 end 36 37 upper1, upper2: INTEGER 38 -- Upper index bounds. 39 deferred 40 end 41 42 frozen line_maximum: INTEGER 43 -- Equivalent of `upper1'. 44 do 45 Result := upper1 46 end 47 48 frozen column_maximum: INTEGER 49 -- Equivalent of `upper2'. 50 do 51 Result := upper2 52 end 53 54feature {ANY} -- Reading: 55 item (line, column: INTEGER): E_ 56 require 57 valid_index(line, column) 58 deferred 59 end 60 61feature {ANY} -- Writing: 62 put (element: like item; line, column: INTEGER) assign item 63 require 64 valid_index(line, column) 65 deferred 66 ensure 67 item(line, column) = element 68 end 69 70 force (element: like item; line, column: INTEGER) 71 -- Put `element' at position (`line',`column'). Collection 72 -- resized first when (`line',`column') is not inside current 73 -- bounds. New bounds are initialized with default values. 74 require 75 line >= 0 76 column >= 0 77 deferred 78 ensure 79 item(line, column) = element 80 count >= old count 81 end 82 83feature {ANY} -- Index validity: 84 frozen valid_line, valid_index1 (line: INTEGER): BOOLEAN 85 do 86 Result := lower1 <= line and then line <= upper1 87 ensure 88 Result = (lower1 <= line and line <= upper1) 89 end 90 91 frozen valid_column, valid_index2 (column: INTEGER): BOOLEAN 92 do 93 Result := lower2 <= column and then column <= upper2 94 ensure 95 Result = (lower2 <= column and column <= upper2) 96 end 97 98 frozen valid_index (line, column: INTEGER): BOOLEAN 99 do 100 Result := lower1 <= line and then line <= upper1 and then lower2 <= column and then column <= upper2 101 ensure 102 Result = (valid_line(line) and valid_column(column)) 103 end 104 105feature {ANY} -- Counting: 106 count1: INTEGER 107 -- Size of the first dimension. 108 deferred 109 ensure 110 Result = upper1 - lower1 + 1 111 end 112 113 frozen line_count: INTEGER 114 -- Equivalent of `count1'. 115 do 116 Result := count1 117 end 118 119 count2: INTEGER 120 -- Size of the second dimension. 121 deferred 122 ensure 123 Result = upper2 - lower2 + 1 124 end 125 126 frozen column_count: INTEGER 127 do 128 Result := count2 129 end 130 131 count: INTEGER 132 -- Total number of elements. 133 deferred 134 ensure 135 Result = line_count * column_count 136 end 137 138feature {ANY} 139 swap (line1, column1, line2, column2: INTEGER) 140 -- Swap the element at index (`line1',`column1') with the 141 -- the element at index (`line2',`column2'). 142 require 143 valid_index(line1, column1) 144 valid_index(line2, column2) 145 deferred 146 ensure 147 item(line1, column1) = old item(line2, column2) 148 item(line2, column2) = old item(line1, column1) 149 count = old count 150 end 151 152 set_all_with (v: like item) 153 -- Set all item with value `v'. 154 deferred 155 ensure 156 count = old count 157 end 158 159 frozen clear_all 160 -- Set all items to default values. 161 local 162 value: like item 163 do 164 set_all_with(value) 165 ensure 166 count = old count 167 all_default 168 end 169 170feature {ANY} -- Creating or initializing: 171 from_collection2 (model: COLLECTION2[like item]) 172 -- Uses `model' to initialize Current. 173 require 174 model /= Void 175 deferred 176 ensure 177 count1 = model.count1 178 count2 = model.count2 179 end 180 181 from_model (model: COLLECTION[COLLECTION[E_]]) 182 -- The `model' is used to fill line by line Current. 183 -- Assume all sub-collections of `model' have the same 184 -- number of lines. 185 require 186 model.count >= 0 187 model.count > 0 implies model.first.count >= 0 188 deferred 189 ensure 190 count1 = model.count 191 count1 > 0 implies count2 = model.first.count 192 count1 = 0 implies count2 = 0 193 end 194 195feature {ANY} -- Looking and comparison: 196 all_default: BOOLEAN 197 -- Do all items have their type's default value? 198 deferred 199 end 200 201 fast_is_equal (other: like Current): BOOLEAN 202 -- Do both collections have the same `lower1', `lower2', `upper1' and `upper2', and items? 203 -- The basic `=' is used for comparison of items. 204 -- See also `is_equal'. 205 local 206 line, column: INTEGER 207 do 208 if lower1 /= other.lower1 then 209 elseif upper1 /= other.upper1 then 210 elseif lower2 /= other.lower2 then 211 elseif upper2 /= other.upper2 then 212 else 213 from 214 Result := True 215 line := upper1 216 until 217 not Result or else line < lower1 218 loop 219 from 220 column := upper2 221 until 222 not Result or else column < lower2 223 loop 224 Result := item(line, column) = other.item(line, column) 225 column := column - 1 226 end 227 line := line - 1 228 end 229 end 230 end 231 232 is_equal (other: like Current): BOOLEAN 233 -- Do both collections have the same `lower1', `lower2', `upper1' and `upper2', and items? 234 -- Feature `is_equal' is used for comparison of items. 235 -- See also `fast_is_equal'. 236 local 237 line, column: INTEGER 238 do 239 if lower1 /= other.lower1 then 240 elseif upper1 /= other.upper1 then 241 elseif lower2 /= other.lower2 then 242 elseif upper2 /= other.upper2 then 243 else 244 from 245 Result := True 246 line := upper1 247 until 248 not Result or else line < lower1 249 loop 250 from 251 column := upper2 252 until 253 not Result or else column < lower2 254 loop 255 Result := safe_equal(item(line, column), other.item(line, column)) 256 column := column - 1 257 end 258 line := line - 1 259 end 260 end 261 end 262 263 is_equal_map (other: like Current): BOOLEAN 264 -- Do both collections have the same `lower', `upper', and 265 -- items? 266 -- Feature `is_equal' is used for comparison of items. 267 obsolete "Use `is_equal' instead." 268 do 269 Result := is_equal(other) 270 end 271 272feature {ANY} -- Printing: 273 frozen fill_tagged_out_memory 274 local 275 line, column: INTEGER; v: like item 276 do 277 tagged_out_memory.append(once "lower1: ") 278 lower1.append_in(tagged_out_memory) 279 tagged_out_memory.append(once " upper1: ") 280 upper1.append_in(tagged_out_memory) 281 tagged_out_memory.append(once " lower2: ") 282 lower2.append_in(tagged_out_memory) 283 tagged_out_memory.append(once " upper2: ") 284 upper2.append_in(tagged_out_memory) 285 tagged_out_memory.append(once " [%N") 286 from 287 line := lower1 288 until 289 line > upper1 or else tagged_out_memory.count > 4096 290 loop 291 tagged_out_memory.append(once "line ") 292 line.append_in(tagged_out_memory) 293 tagged_out_memory.append(once "%T: ") 294 from 295 column := lower2 296 until 297 column > upper2 298 loop 299 v := item(line, column) 300 if v = Void then 301 tagged_out_memory.append(once "Void") 302 else 303 v.out_in_tagged_out_memory 304 end 305 tagged_out_memory.extend(' ') 306 column := column + 1 307 end 308 tagged_out_memory.extend('%N') 309 line := line + 1 310 end 311 if valid_line(line) then 312 tagged_out_memory.append(once "......%N") 313 end 314 end 315 316feature {ANY} -- Miscellaneous features: 317 occurrences (elt: E_): INTEGER 318 -- Number of occurrences using `is_equal'. 319 -- See also `fast_occurrences' to choose the appropriate one. 320 deferred 321 ensure 322 Result >= 0 323 end 324 325 fast_occurrences (elt: E_): INTEGER 326 -- Number of occurrences using `='. 327 -- See also `occurrences' to chose the appropriate one. 328 deferred 329 ensure 330 Result >= 0 331 end 332 333 has (x: like item): BOOLEAN 334 -- Search if a element x is in the array using `is_equal'. 335 -- See also `fast_has' to chose the appropriate one. 336 deferred 337 end 338 339 fast_has (x: like item): BOOLEAN 340 -- Search if a element x is in the array using `='. 341 deferred 342 end 343 344 replace_all (old_value, new_value: like item) 345 -- Replace all occurrences of the element `old_value' by `new_value' 346 -- using `is_equal' for comparison. 347 -- See also `fast_replace_all' to choose the appropriate one. 348 deferred 349 ensure 350 count = old count 351 occurrences(old_value) = 0 352 end 353 354 fast_replace_all (old_value, new_value: like item) 355 -- Replace all occurrences of the element `old_value' by `new_value' 356 -- using operator `=' for comparison. 357 -- See also `replace_all' to choose the appropriate one. 358 deferred 359 ensure 360 count = old count 361 fast_occurrences(old_value) = 0 362 end 363 364 sub_collection2 (line_min, line_max, column_min, column_max: INTEGER): like Current 365 -- Create a new object using selected area of `Current'. 366 require 367 valid_index(line_min, column_min) 368 valid_index(line_max, column_max) 369 line_min <= line_max + 1 370 column_min <= column_max + 1 371 deferred 372 ensure 373 Result /= Void 374 end 375 376 set_area (element: like item; line_min, line_max, column_min, column_max: INTEGER) 377 -- Set all the elements of the selected area rectangle with `element'. 378 require 379 valid_index(line_min, column_min) 380 valid_index(line_max, column_max) 381 local 382 line, column: INTEGER 383 do 384 from 385 line := line_min 386 until 387 line > line_max 388 loop 389 from 390 column := column_min 391 until 392 column > column_max 393 loop 394 put(element, line, column) 395 column := column + 1 396 end 397 line := line + 1 398 end 399 ensure 400 count = old count 401 end 402 403feature {} -- Implement manifest generic creation: 404 manifest_put (index: INTEGER; element: like item) 405 require 406 index >= 0 407 deferred 408 end 409 410 manifest_semicolon_check: BOOLEAN True 411 -- You can use semicolons to make the end of each line more visible. 412 413end -- class COLLECTION2 414-- 415-- Copyright (C) 2009-2017: by all the people cited in the AUTHORS file. 416-- 417-- Permission is hereby granted, free of charge, to any person obtaining a copy 418-- of this software and associated documentation files (the "Software"), to deal 419-- in the Software without restriction, including without limitation the rights 420-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 421-- copies of the Software, and to permit persons to whom the Software is 422-- furnished to do so, subject to the following conditions: 423-- 424-- The above copyright notice and this permission notice shall be included in 425-- all copies or substantial portions of the Software. 426-- 427-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 428-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 429-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 430-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 431-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 432-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 433-- THE SOFTWARE.