PageRenderTime 29ms CodeModel.GetById 13ms app.highlight 7ms RepoModel.GetById 1ms app.codeStats 1ms

/src/lib/storage/collection2.e

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