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