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]
|