PageRenderTime 23ms CodeModel.GetById 13ms app.highlight 6ms RepoModel.GetById 1ms app.codeStats 1ms

/src/lib/storage/collection3.e

http://github.com/tybor/Liberty
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.