File: fixed_array.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 (314 lines) | stat: -rw-r--r-- 8,090 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
-- 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 FIXED_ARRAY[E]
   --
   -- Resizable, fixed lower bound array.
   -- Unlike ARRAY, the `lower' bound of a FIXED_ARRAY is frozen
   -- to 0. Thus, some memory is saved and looping toward `lower'
   -- bound (which is 0) run a little bit faster.
   --

inherit ARRAYED_COLLECTION[E]

creation
   make, with_capacity, from_collection

feature

   lower: INTEGER is 0
         -- Frozen lower bound.

feature -- Creation and modification:

   make(new_count: INTEGER) is
         -- Make array with range [0 .. `new_count' - 1].
         -- When `new_count' = 0 the array is empty.
      require
         new_count >= 0
      do
	 if new_count > capacity then
	    -- The new one is bigger:
            storage := storage.calloc(new_count)
            capacity := new_count
	 elseif capacity > 0 then
 	    -- storage is big enough and just need to be cleared:
	    upper := upper.max(new_count - 1)
	    if upper >= 0 then
	       storage.clear_all(upper)
	    end
	 end
	 upper := new_count - 1
      ensure
         count = new_count
         capacity >= old capacity
         all_default
      end

   with_capacity(needed_capacity: INTEGER) is
         -- Create an empty array with at least `needed_capacity'.
      require
	 needed_capacity >= 0
      do
         if capacity < needed_capacity then
            storage := storage.calloc(needed_capacity)
            capacity := needed_capacity
	 elseif capacity > needed_capacity then
	    storage.clear(0,upper)
         end
         upper := -1
      ensure
         capacity >= needed_capacity
         is_empty
      end

feature -- Modification:

   resize(new_count: INTEGER) is
         -- Resize the array. When `new_count' is greater than
         -- `count', new positions are initialized with appropriate
         -- default values.
      require
         new_count >= 0
      local
         new_capacity: INTEGER
      do
         if new_count > count then
	    if capacity = 0 then
	       storage := storage.calloc(new_count)
	       capacity := new_count
	    elseif capacity < new_count then
	       from
		  new_capacity := capacity * 2
	       until
		  new_capacity >= new_count
	       loop
		  new_capacity := new_capacity * 2
	       end
	       storage := storage.realloc(capacity,new_capacity)
	       capacity := new_capacity
            end
         elseif new_count /= count then
	    storage.clear(new_count,count - 1)
	 end
	 upper := new_count - 1
      ensure
         count = new_count
         capacity >= old capacity
      end

feature -- Implementation of deferred:

   is_empty: BOOLEAN is
      do
         Result := upper < 0
      end

   item, infix "@" (i: INTEGER): E is
      do
         Result := storage.item(i)
      end

   put(element: E; i: INTEGER) is
      do
         storage.put(element,i)
      end

   add_first(element: like item) is
      do
         add_last(element)
         if upper = 0 then
         elseif upper = 1 then
            swap(0,1)
         else
            move(0,upper - 1,1)
            storage.put(element,0)
         end
      end

   add_last(element: like item) is
      local
         new_capacity: INTEGER
      do
         if upper + 1 <= capacity - 1 then
            upper := upper + 1
         elseif capacity = 0 then
            storage := storage.calloc(2)
            capacity := 2
            upper := 0
         else
            new_capacity := 2 * capacity
            storage := storage.realloc(capacity,new_capacity)
            capacity := new_capacity
            upper := upper + 1
         end
         storage.put(element,upper)
      end

   count: INTEGER is
      do
         Result := upper + 1
      end

   clear is
      do
         upper := -1
      ensure then
         capacity = old capacity
      end

   copy(other: like Current) is
         -- Copy `other' onto Current.
      local
         other_upper, new_capacity: INTEGER
      do
         other_upper := other.upper
         if other_upper >= 0 then
            new_capacity := other_upper + 1
            if capacity < new_capacity then
               storage := storage.calloc(new_capacity)
               capacity := new_capacity
            elseif capacity > 0 then
               storage.clear_all(capacity - 1)
            end
            storage.copy_from(other.storage,other_upper)
         elseif capacity > 0 then
            storage.clear_all(capacity - 1)
         end
         upper := other_upper
      end

   set_all_with(v: like item) is
      do
         storage.set_all_with(v,upper)
      end

   from_collection(model: COLLECTION[like item]) is
      local
         i1, i2, up: INTEGER
      do
         from
            with_capacity(model.count)
            upper := model.count - 1
            i1 := 0
            i2 := model.lower
            up := model.upper
         until
            i2 > up
         loop
            storage.put(model.item(i2),i1)
            i1 := i1 + 1
            i2 := i2 + 1
         end
      end

   is_equal(other: like Current): BOOLEAN is
      do
         if Current = other then
            Result := true
         elseif upper = other.upper then
            Result := storage.fast_memcmp(other.storage,upper + 1)
         end
      end

   is_equal_map(other: like Current): BOOLEAN is
      do
         if Current = other then
            Result := true
         elseif upper = other.upper then
            Result := storage.memcmp(other.storage,upper + 1)
         end
      end

   all_default: BOOLEAN is
      do
         Result := storage.all_default(upper)
      end

   occurrences(element: like item): INTEGER is
      do
         Result := storage.occurrences(element,upper)
      end

   fast_occurrences(element: E): INTEGER is
      do
         Result := storage.fast_occurrences(element,upper)
      end

   index_of(element: like item): INTEGER is
      do
         Result := storage.index_of(element,upper)
      end

   first_index_of(element: like item): INTEGER is
      do
         Result := storage.index_of(element,upper)
      end

   fast_index_of(element: like item): INTEGER is
      do
         Result := storage.fast_index_of(element,upper)
      end

   subarray, slice(min, max: INTEGER): like Current is
      do
	 !!Result.make(max - min + 1)
	 Result.storage.copy_slice(0,storage,min, max)
      end

   force(element: E; index: INTEGER) is
      do
         if index <= upper then
            storage.put(element,index)
         elseif index = upper + 1 then
            add_last(element)
         else
            resize(index + 1)
            storage.put(element,index)
         end
      end

   remove_first is
      local
         void_storage: like storage
      do
         if upper = 0 then
            storage := void_storage
            capacity := 0
            upper := -1
         else
            storage.remove_first(upper)
            upper := upper - 1
         end
      ensure then
         lower = old lower
      end

   remove(index: INTEGER) is
      do
         storage.remove(index,upper)
         upper := upper - 1
      end

   get_new_iterator: ITERATOR[E] is
      do
         !ITERATOR_ON_COLLECTION[E]!Result.make(Current)
      end

end -- FIXED_ARRAY[E]