File: array3.e

package info (click to toggle)
smarteiffel 1.1-11
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 12,288 kB
  • ctags: 40,785
  • sloc: ansic: 35,791; lisp: 4,036; sh: 1,783; java: 895; ruby: 613; python: 209; makefile: 115; csh: 78; cpp: 50
file content (424 lines) | stat: -rw-r--r-- 11,406 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
-- This  file  is  free software,  which comes along with SmartEiffel.  This
-- software is distributed in the hope that it will be useful,  but  WITHOUT
-- ANY  WARRANTY;  without  even the  implied warranty of MERCHANTABILITY or
-- FITNESS FOR A PARTICULAR PURPOSE. You can modify it as you want, provided
-- this header is kept unaltered, and a notification of the changes is added.
-- You  are  allowed  to  redistribute it and sell it, alone or as a part of
-- another product.
--
-- Copyright(C) 1994-2002: INRIA - LORIA (INRIA Lorraine) - ESIAL U.H.P.
--			   - University of Nancy 1 - FRANCE
-- Copyright(C) 2003:      INRIA - LORIA (INRIA Lorraine) - I.U.T. Charlemagne
--			   - University of Nancy 2 - FRANCE
--
--		 Dominique COLNET, Suzanne COLLIN, Olivier ZENDRA,
--			   Philippe RIBET, Cyril ADRIAN
--
-- http://SmartEiffel.loria.fr - SmartEiffel@loria.fr
--
class ARRAY3[E]
   --
   -- General prurpose, resizable, three dimensional array.
   --

inherit COLLECTION3[E]

creation
   make, copy, from_collection3, from_collection, from_model

feature

   lower1, lower2, lower3, upper1, upper2, upper3: INTEGER

   count1, count2, count3, count: INTEGER

feature {ARRAY3}

   storage: NATIVE_ARRAY[E]
	 -- To store elements line by line.

   capacity: INTEGER
	 -- Number of elements in `storage'.

feature -- Creation / modification:

   make(line_min, line_max, column_min, column_max, depth_min, depth_max: INTEGER) is
         -- Reset all bounds `line_minimum' / `line_maximum' / `column_minimum'
         -- `column_maximum' / `depth_min' and `depth_max' using arguments as
         -- new values. All elements are set to the default value of type E.
      require
	 line_min <= line_max
         column_min <= column_max
         depth_min <= depth_max
      do
	 lower1 := line_min
	 upper1 := line_max
	 lower2 := column_min
	 upper2 := column_max
         lower3 := depth_min
         upper3 := depth_max
	 count1 := upper1 - lower1 + 1
	 count2 := upper2 - lower2 + 1
	 count3 := upper3 - lower3 + 1
	 count := count1 * count2 * count3
	 if capacity >= count then
	    storage.clear_all(count - 1)
	 else
	    capacity := count
	    storage := storage.calloc(count)
	 end
      ensure
	 line_minimum = line_min
	 line_maximum = line_max
	 column_minimum = column_min
	 column_maximum = column_max
         depth_minimum = depth_min
         depth_maximum = depth_max
      end

   from_collection3(model: COLLECTION3[like item]) is
      local
         i, j, k: INTEGER
      do
	 make(model.line_minimum,
	      model.line_maximum,
	      model.column_minimum,
              model.column_maximum,
              model.depth_minimum,
              model.depth_maximum)
	 from
	    i := line_minimum
	 until
	    i > line_maximum
	 loop
	    from
	       j := column_minimum
	    until
	       j > column_maximum
	    loop
               from
                  k := depth_minimum
               until
                  k > depth_maximum
               loop
                  put(model.item(i,j,k),i,j,k)
                  k := k + 1
               end
   	       j := j + 1
	    end
	    i := i + 1
	 end
      ensure then
	 lower1 = model.lower1
         lower2 = model.lower2
         lower3 = model.lower3
      end

   from_collection(contents: COLLECTION[E]
        line_min, line_max, column_min, column_max, depth_min, depth_max: INTEGER) is
	 --  Reset all bounds using `line_min', `line_max', `column_min',
         --  `column_max', `depth_min', and `depth_max'.
	 --  Copy all elements of `contents', line by line into Current.
      require
	 line_min <= line_max
	 column_min <= column_max
         depth_min <= depth_max
         contents.count = (line_max - line_min + 1) * (column_max - column_min + 1) * (depth_max - depth_min + 1)
      local
	 i: INTEGER
      do
         make(line_min,line_max,column_min,column_max,depth_min,depth_max)
	 from
	    i := 0
	 until
	    i >= count
	 loop
	    storage.put(contents.item(contents.lower + i),i)
	    i := i + 1
	 end
      ensure
	 line_minimum = line_min
	 line_maximum = line_max
	 column_minimum = column_min
	 column_maximum = column_max
         depth_minimum = depth_min
         depth_maximum = depth_max
         count = contents.count
      end

   from_model(model: COLLECTION[COLLECTION[COLLECTION[E]]]) is
         -- The `model' is used to fill line by line the COLLECTION3.
         -- Assume all sub-collections of have the same indexing.
      local
         line, column, depth: INTEGER
      do
	 make(model.lower,
	      model.upper,
	      model.first.lower,
              model.first.upper,
              model.first.first.lower,
              model.first.first.upper)
	 from
	    line := model.lower
	 until
	    line > model.upper
	 loop
	    from
	       column := model.first.lower
	    until
	       column > model.first.upper
	    loop
               from
                  depth := model.first.first.lower
               until
                  depth > model.first.first.upper
               loop
                  put(model.item(line).item(column).item(depth),line,column,depth)
                  depth := depth + 1
               end
	       column := column + 1
	    end
	    line := line + 1
	 end
      ensure then
	 line_minimum = model.lower
	 line_maximum = model.upper
	 column_minimum = model.first.lower
         column_maximum = model.first.upper
         depth_minimum = model.first.first.lower
         depth_maximum = model.first.first.upper
      end

feature -- Resizing:

   resize(line_min, line_max, column_min, column_max, depth_min, depth_max: INTEGER) is
	 -- Resize bounds of the Current array
      require
	 line_max >= line_min
	 column_max >= column_min
         depth_max >= depth_min
      local
	 tmp: like Current
         l, c, d: INTEGER
      do
         !!tmp.make(line_min, line_max, column_min, column_max, depth_min, depth_max)
         -- It may be possible to avoid this creation when :
	 --    new `capacity' <= old `capacity'
	 from
	    l := lower1
	 until
	    l > line_maximum
	 loop
	    from
	       c := lower2
	    until
	       c > column_maximum
	    loop
               from
                  d := lower3
               until
                  d > depth_maximum
               loop
                  if tmp.valid_index(l,c,d) then
                     tmp.put(item(l,c,d),l,c,d)
                  end
                  d := d + 1
               end
	       c := c + 1
	    end
	    l := l + 1
	 end
	 standard_copy(tmp)
      ensure
	 line_minimum = line_min
	 line_maximum = line_max
	 column_minimum = column_min
	 column_maximum = column_max
         depth_minimum = depth_min
         depth_maximum = depth_max
      end

feature -- Implementation of others feature from COLLECTION3:

   item(line, column, depth: INTEGER): E is
      do
         Result := storage.item((line - lower1) * count2 * count3 + (column - lower2) * count3 + depth - lower3)
      end

   put(element: like item; line, column, depth: INTEGER) is
      do
         storage.put(element,(line - lower1) * count2 * count3 + (column - lower2) * count3 + depth - lower3)
      end

   force(x: like item; line, column, depth: INTEGER) is
      require else
	 True
      do
         if not valid_index(line,column,depth) then
	    resize(line.min(lower1),
		   line.max(upper1),
		   column.min(lower2),
                   column.max(upper2),
                   depth.min(lower3),
                   depth.max(upper3))
	 end
         put(x,line,column,depth)
      end

   set_all_with(element: E) is
      do
	 storage.set_all_with(element,count - 1)
      end

   replace_all(old_value, new_value: like item) is
      do
	 storage.replace_all(old_value,new_value,count - 1)
      end

   fast_replace_all(old_value, new_value: like item) is
      do
	 storage.fast_replace_all(old_value,new_value,count - 1)
      end

   sub_collection3(line_min, line_max, column_min, column_max,
                   depth_min, depth_max: INTEGER): like Current is
      local
         i, j, k, n: INTEGER
      do
         !!Result.make(line_min,line_max,column_min,column_max,
                       depth_min,depth_max)
	 from
	    i := line_min
	    k := 0
	 until
	    i > line_max
	 loop
	    from
	       j := column_min
	    until
	       j > column_max
	    loop
               from
                  k := depth_min
               until
                  k > depth_max
               loop
                  Result.storage.put(item(i,j,k),n)
                  n := n + 1
                  k := k + 1
               end
               j := j + 1
	    end
	    i := i + 1
	 end
      ensure then
	 Result.lower1 = line_min
	 Result.lower2 = column_min
         Result.lower3 = depth_min
	 Result.upper1 = line_max
	 Result.upper2 = column_max
         Result.upper3 = depth_max
      end

feature --  Looking and comparison:

   occurrences(elt: E): INTEGER is
      do
	 Result := storage.occurrences(elt,count - 1)
      end

   fast_occurrences(elt: E): INTEGER is
      do
	 Result := storage.fast_occurrences(elt,count - 1)
      end

   has(x: like item): BOOLEAN is
	 -- Search if a element x is in the array using `equal'.
         -- See also `fast_has' to choose the apropriate one.
      do
	 Result := storage.index_of(x,count - 1) <= count - 1
      end

   fast_has(x: like item): BOOLEAN is
	 --  Search if a element x is in the array using `='.
      do
	 Result := storage.fast_index_of(x,count - 1) <= count -1
      end

   all_default: BOOLEAN is
      do
	 result := storage.all_default(count - 1)
      end

   swap(line1, column1, depth1, line2, column2, depth2 : INTEGER) is
      local
	 tmp: like item
         index1, index2: INTEGER
      do
         index1 := (line1 - lower1) * count2 * count3 + (column1 - lower2) * count3 + depth1 - lower3
         index2 := (line2 - lower1) * count2 * count3 + (column2 - lower2) * count3 + depth2 - lower3
	 tmp := storage.item(index1)
	 storage.put(storage.item(index2),index1)
	 storage.put(tmp,index2)
      end

   copy(other: like Current) is
      do
	 lower1 := other.lower1
	 upper1 := other.upper1
	 lower2 := other.lower2
	 upper2 := other.upper2
         lower3 := other.lower3
         upper3 := other.upper3
	 count := other.count
	 count1 := other.count1
	 count2 := other.count2
	 count3 := other.count3
	 if capacity < count then
	    capacity := count
	    storage := storage.calloc(count)
	 end
	 storage.copy_from(other.storage, count - 1)
      end

   is_equal(other: like Current): BOOLEAN is
      do
	 if other = Current then
	    Result := True
	 elseif lower1 /= other.lower1 then
	 elseif lower2 /= other.lower2 then
         elseif lower3 /= other.lower3 then
         elseif upper1 /= other.upper1 then
         elseif upper2 /= other.upper2 then
         elseif upper3 /= other.upper3 then
	 else
	    Result := storage.memcmp(other.storage,count)
	 end
      end

   same_as(other: COLLECTION3[E]): BOOLEAN is
      do
         Result := other.same_as_array3(Current)
      end

feature {COLLECTION3}

   same_as_array3(other: ARRAY3[E]): BOOLEAN is
      do
	 Result := standard_same_as(other)
      end

   same_as_fixed_array3(other: FIXED_ARRAY3[E]): BOOLEAN is
      do
	 Result := standard_same_as(other)
      end

invariant

   count1 = upper1 - lower1 + 1
   count2 = upper2 - lower2 + 1
   count3 = upper3 - lower3 + 1

   capacity >= count

end -- ARRAY3[E]