OMCompiler/Compiler/Util/Vector.mo
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * This file is part of OpenModelica. | ||
| 3 | * | ||
| 4 | * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC), | ||
| 5 | * c/o Linköpings universitet, Department of Computer and Information Science, | ||
| 6 | * SE-58183 Linköping, Sweden. | ||
| 7 | * | ||
| 8 | * All rights reserved. | ||
| 9 | * | ||
| 10 | * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF AGPL VERSION 3 LICENSE OR | ||
| 11 | * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8. | ||
| 12 | * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES | ||
| 13 | * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GNU AGPL | ||
| 14 | * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. | ||
| 15 | * | ||
| 16 | * The OpenModelica software and the OSMC (Open Source Modelica Consortium) | ||
| 17 | * Public License (OSMC-PL) are obtained from OSMC, either from the above | ||
| 18 | * address, from the URLs: | ||
| 19 | * http://www.openmodelica.org or | ||
| 20 | * https://github.com/OpenModelica/ or | ||
| 21 | * http://www.ida.liu.se/projects/OpenModelica, | ||
| 22 | * and in the OpenModelica distribution. | ||
| 23 | * | ||
| 24 | * GNU AGPL version 3 is obtained from: | ||
| 25 | * https://www.gnu.org/licenses/licenses.html#GPL | ||
| 26 | * | ||
| 27 | * This program is distributed WITHOUT ANY WARRANTY; without | ||
| 28 | * even the implied warranty of MERCHANTABILITY or FITNESS | ||
| 29 | * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH | ||
| 30 | * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL. | ||
| 31 | * | ||
| 32 | * See the full OSMC Public License conditions for more details. | ||
| 33 | * | ||
| 34 | */ | ||
| 35 | |||
| 36 | encapsulated uniontype Vector<T> | ||
| 37 | "An implementation of a generic dynamic array." | ||
| 38 | |||
| 39 | import Mutable; | ||
| 40 | |||
| 41 | protected | ||
| 42 | import MetaModelica.Dangerous.*; | ||
| 43 | |||
| 44 | public | ||
| 45 | record VECTOR | ||
| 46 | Mutable<array<T>> data; | ||
| 47 | Mutable<Integer> size "The number of stored elements."; | ||
| 48 | end VECTOR; | ||
| 49 | |||
| 50 | function new<T> | ||
| 51 | "Creates a new empty Vector." | ||
| 52 | input Integer size = 0 "Initial capacity"; | ||
| 53 | output Vector<T> v; | ||
| 54 | protected | ||
| 55 | T dummy = dummy; | ||
| 56 | algorithm | ||
| 57 | 2094921 | v := VECTOR(Mutable.create(arrayCreateNoInit(size, dummy)), | |
| 58 | Mutable.create(0)); | ||
| 59 | end new; | ||
| 60 | |||
| 61 | function newFill | ||
| 62 | "Creates a new Vector filled with the given value." | ||
| 63 | input Integer size; | ||
| 64 | input T value; | ||
| 65 | output Vector<T> v; | ||
| 66 | algorithm | ||
| 67 | 685705 | v := VECTOR(Mutable.create(arrayCreate(size, value)), | |
| 68 | Mutable.create(size)); | ||
| 69 | end newFill; | ||
| 70 | |||
| 71 | function fromArray | ||
| 72 | "Creates a Vector from an array." | ||
| 73 | input array<T> arr; | ||
| 74 | output Vector<T> v; | ||
| 75 | algorithm | ||
| 76 | 472 | v := VECTOR(Mutable.create(arrayCopy(arr)), | |
| 77 | Mutable.create(arrayLength(arr))); | ||
| 78 | end fromArray; | ||
| 79 | |||
| 80 | function fromArrayNoCopy | ||
| 81 | "Creates a Vector that takes ownership of the given array. size defaults to | ||
| 82 | the whole array; give a smaller one to keep the rest as spare capacity." | ||
| 83 | input array<T> arr; | ||
| 84 | input Integer size = -1; | ||
| 85 | output Vector<T> v; | ||
| 86 | algorithm | ||
| 87 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 15283 times.
|
15283 | v := VECTOR(Mutable.create(arr), Mutable.create(if size < 0 then arrayLength(arr) else size)); |
| 88 | end fromArrayNoCopy; | ||
| 89 | |||
| 90 | function rawArray | ||
| 91 | "Returns the internal array of the Vector. It may be larger than the | ||
| 92 | Vector's size, and is invalidated whenever the Vector grows." | ||
| 93 | input Vector<T> v; | ||
| 94 | output array<T> arr; | ||
| 95 | algorithm | ||
| 96 | 38844 | arr := Mutable.access(v.data); | |
| 97 | end rawArray; | ||
| 98 | |||
| 99 | function toArray | ||
| 100 | "Converts a Vector to an array." | ||
| 101 | input Vector<T> v; | ||
| 102 | output array<T> arr; | ||
| 103 | protected | ||
| 104 | array<T> data = Mutable.access(v.data); | ||
| 105 | Integer sz = Mutable.access(v.size); | ||
| 106 | T dummy = dummy; | ||
| 107 | algorithm | ||
| 108 |
2/2✓ Branch 0 taken 608 times.
✓ Branch 1 taken 166 times.
|
774 | if sz == arrayLength(data) then |
| 109 | // If the Vector is filled to capacity, just make a copy of the internal array. | ||
| 110 | 608 | arr := arrayCopy(data); | |
| 111 | else | ||
| 112 | 166 | arr := arrayCreateNoInit(sz, dummy); | |
| 113 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 164 times.
|
850 | for i in 1:sz loop |
| 114 | 684 | arrayUpdateNoBoundsChecking(arr, i, arrayGetNoBoundsChecking(data, i)); | |
| 115 | end for; | ||
| 116 | end if; | ||
| 117 | end toArray; | ||
| 118 | |||
| 119 | function fromList | ||
| 120 | "Creates a Vector from a list." | ||
| 121 | input list<T> l; | ||
| 122 | output Vector<T> v; | ||
| 123 | protected | ||
| 124 | array<T> data = listArray(l); | ||
| 125 | algorithm | ||
| 126 | 116 | v := VECTOR(Mutable.create(data), Mutable.create(arrayLength(data))); | |
| 127 | end fromList; | ||
| 128 | |||
| 129 | function toList | ||
| 130 | "Converts a Vector to a list." | ||
| 131 | input Vector<T> v; | ||
| 132 | output list<T> l; | ||
| 133 | protected | ||
| 134 | array<T> data = Mutable.access(v.data); | ||
| 135 | Integer sz = Mutable.access(v.size); | ||
| 136 | algorithm | ||
| 137 |
2/2✓ Branch 0 taken 210094 times.
✓ Branch 1 taken 79183 times.
|
289277 | if sz == arrayLength(data) then |
| 138 | // If the Vector is filled to capacity, use the faster arrayList. | ||
| 139 | 210094 | l := arrayList(data); | |
| 140 | else | ||
| 141 |
2/2✓ Branch 0 taken 922248 times.
✓ Branch 1 taken 79183 times.
|
1001431 | l := list(arrayGetNoBoundsChecking(data, i) for i in 1:sz); |
| 142 | end if; | ||
| 143 | end toList; | ||
| 144 | |||
| 145 | function push | ||
| 146 | "Appends a value to the end of the Vector." | ||
| 147 | input Vector<T> v; | ||
| 148 | input T value; | ||
| 149 | protected | ||
| 150 | array<T> data; | ||
| 151 | Integer sz = Mutable.access(v.size); | ||
| 152 | algorithm | ||
| 153 | 9388200 | sz := sz + 1; | |
| 154 | 9388200 | Mutable.update(v.size, sz); | |
| 155 | |||
| 156 | 9388200 | data := reserveCapacity(v, sz); | |
| 157 | arrayUpdateNoBoundsChecking(data, sz, value); | ||
| 158 | end push; | ||
| 159 | |||
| 160 | function insert | ||
| 161 | "Inserts a value at the given index, moving the elements after to make place. | ||
| 162 | Fails if the index is out of bounds, except for when the index is one past | ||
| 163 | the end of the vector in which case the operation is equivalent to a push | ||
| 164 | (to allow inserting at the end of the vector)." | ||
| 165 | input Vector<T> v; | ||
| 166 | input T value; | ||
| 167 | input Integer index; | ||
| 168 | protected | ||
| 169 | array<T> data; | ||
| 170 | Integer sz = Mutable.access(v.size); | ||
| 171 | algorithm | ||
| 172 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if index == sz + 1 then |
| 173 | ✗ | push(v, value); | |
| 174 | elseif index < 1 or index > sz then | ||
| 175 | ✗ | fail(); | |
| 176 | end if; | ||
| 177 | |||
| 178 | sz := sz + 1; | ||
| 179 | 2 | Mutable.update(v.size, sz); | |
| 180 | 2 | data := reserveCapacity(v, sz); | |
| 181 | |||
| 182 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
7 | for i in sz:-1:index+1 loop |
| 183 | 5 | arrayUpdateNoBoundsChecking(data, i, arrayGetNoBoundsChecking(data, i - 1)); | |
| 184 | end for; | ||
| 185 | |||
| 186 | arrayUpdateNoBoundsChecking(data, index, value); | ||
| 187 | end insert; | ||
| 188 | |||
| 189 | function append | ||
| 190 | "Appends v2 to the end of v1." | ||
| 191 | input Vector<T> v1; | ||
| 192 | input Vector<T> v2; | ||
| 193 | protected | ||
| 194 | array<T> data1; | ||
| 195 | Integer sz1 = Mutable.access(v1.size); | ||
| 196 | array<T> data2 = Mutable.access(v2.data); | ||
| 197 | Integer sz2 = Mutable.access(v2.size); | ||
| 198 | Integer new_sz = sz1 + sz2; | ||
| 199 | algorithm | ||
| 200 | ✗ | data1 := reserveCapacity(v1, new_sz); | |
| 201 | |||
| 202 | ✗ | sz1 := sz1 + 1; | |
| 203 | ✗ | for i in 1:arrayLength(data2) loop | |
| 204 | ✗ | arrayUpdateNoBoundsChecking(data1, sz1 + i, | |
| 205 | arrayGetNoBoundsChecking(data2, i)); | ||
| 206 | end for; | ||
| 207 | |||
| 208 | ✗ | Mutable.update(v1.size, new_sz); | |
| 209 | end append; | ||
| 210 | |||
| 211 | function appendList | ||
| 212 | "Appends a list to the end of the Vector." | ||
| 213 | input Vector<T> v; | ||
| 214 | input list<T> l; | ||
| 215 | protected | ||
| 216 | array<T> data; | ||
| 217 | Integer sz = Mutable.access(v.size); | ||
| 218 | Integer new_sz = sz + listLength(l); | ||
| 219 | list<T> rest_l = l; | ||
| 220 | algorithm | ||
| 221 | ✗ | data := reserveCapacity(v, new_sz); | |
| 222 | |||
| 223 | ✗ | for i in sz+1:new_sz loop | |
| 224 | ✗ | arrayUpdateNoBoundsChecking(data, i, listHead(rest_l)); | |
| 225 | ✗ | rest_l := listRest(rest_l); | |
| 226 | end for; | ||
| 227 | |||
| 228 | ✗ | Mutable.update(v.size, new_sz); | |
| 229 | end appendList; | ||
| 230 | |||
| 231 | function appendArray | ||
| 232 | "Appends an array to the end of the Vector." | ||
| 233 | input Vector<T> v; | ||
| 234 | input array<T> arr; | ||
| 235 | protected | ||
| 236 | array<T> data; | ||
| 237 | Integer sz = Mutable.access(v.size); | ||
| 238 | Integer new_sz = sz + arrayLength(arr); | ||
| 239 | algorithm | ||
| 240 | 2 | data := reserveCapacity(v, new_sz); | |
| 241 | |||
| 242 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
4 | for i in 1:arrayLength(arr) loop |
| 243 | 2 | arrayUpdateNoBoundsChecking(data, sz + i, | |
| 244 | arrayGetNoBoundsChecking(arr, i)); | ||
| 245 | end for; | ||
| 246 | |||
| 247 | 2 | Mutable.update(v.size, new_sz); | |
| 248 | end appendArray; | ||
| 249 | |||
| 250 | function pop | ||
| 251 | "Removes the last element in the Vector. Fails if the Vector is empty. | ||
| 252 | Does not change the capacity of the Vector." | ||
| 253 | input Vector<T> v; | ||
| 254 | protected | ||
| 255 | array<T> data = Mutable.access(v.data); | ||
| 256 | Integer sz = Mutable.access(v.size); | ||
| 257 | algorithm | ||
| 258 | arrayClearIndex(data, sz); | ||
| 259 | 15442 | Mutable.update(v.size, sz - 1); | |
| 260 | end pop; | ||
| 261 | |||
| 262 | function clear | ||
| 263 | "Removes all elements from the Vector. | ||
| 264 | Does not change the capacity of the Vector." | ||
| 265 | input Vector<T> v; | ||
| 266 | protected | ||
| 267 | array<T> data = Mutable.access(v.data); | ||
| 268 | algorithm | ||
| 269 |
2/2✓ Branch 1 taken 201987 times.
✓ Branch 2 taken 7560 times.
|
1375612 | for i in 1:Mutable.access(v.size) loop |
| 270 | arrayClearIndex(data, i); | ||
| 271 | end for; | ||
| 272 | |||
| 273 | 209547 | Mutable.update(v.size, 0); | |
| 274 | end clear; | ||
| 275 | |||
| 276 | function shrink | ||
| 277 | "Removes elements from the Vector until it contains newSize elements, or | ||
| 278 | does nothing if newSize is larger than the size of the Vector. | ||
| 279 | Fails if the new size is negative. | ||
| 280 | Does not change the capacity of the Vector." | ||
| 281 | input Vector<T> v; | ||
| 282 | input Integer newSize; | ||
| 283 | protected | ||
| 284 | array<T> data = Mutable.access(v.data); | ||
| 285 | Integer sz = Mutable.access(v.size); | ||
| 286 | algorithm | ||
| 287 | ✗ | if newSize < sz then | |
| 288 | ✗ | for i in newSize:sz loop | |
| 289 | arrayClearIndex(data, i); | ||
| 290 | end for; | ||
| 291 | |||
| 292 | ✗ | Mutable.update(v.size, newSize); | |
| 293 | end if; | ||
| 294 | end shrink; | ||
| 295 | |||
| 296 | function grow | ||
| 297 | input Vector<T> v; | ||
| 298 | input Integer newSize; | ||
| 299 | input T fillValue; | ||
| 300 | protected | ||
| 301 | array<T> data; | ||
| 302 | Integer sz = Mutable.access(v.size); | ||
| 303 | algorithm | ||
| 304 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 199355 times.
|
199355 | if newSize > sz then |
| 305 | 199355 | data := reserveCapacity(v, newSize); | |
| 306 | |||
| 307 |
1/2✓ Branch 0 taken 199355 times.
✗ Branch 1 not taken.
|
3130192 | for i in sz+1:newSize loop |
| 308 | arrayUpdateNoBoundsChecking(data, i, fillValue); | ||
| 309 | end for; | ||
| 310 | |||
| 311 | 199355 | Mutable.update(v.size, newSize); | |
| 312 | end if; | ||
| 313 | end grow; | ||
| 314 | |||
| 315 | function resize | ||
| 316 | input Vector<T> v; | ||
| 317 | input Integer newSize; | ||
| 318 | input T fillValue; | ||
| 319 | protected | ||
| 320 | Integer sz = Mutable.access(v.size); | ||
| 321 | algorithm | ||
| 322 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 199355 times.
|
199355 | if newSize < sz then |
| 323 | ✗ | shrink(v, newSize); | |
| 324 | elseif newSize > sz then | ||
| 325 | 199355 | grow(v, newSize, fillValue); | |
| 326 | end if; | ||
| 327 | end resize; | ||
| 328 | |||
| 329 | function remove | ||
| 330 | "Removes the element at the given index, or fails if the index is out of | ||
| 331 | bounds. The elements after the removed element will be moved to fill the gap." | ||
| 332 | input Vector<T> v; | ||
| 333 | input Integer index; | ||
| 334 | protected | ||
| 335 | Integer sz = Mutable.access(v.size); | ||
| 336 | array<T> data; | ||
| 337 | algorithm | ||
| 338 |
2/2✓ Branch 0 taken 15442 times.
✓ Branch 1 taken 32683 times.
|
48125 | if index == sz then |
| 339 | 15442 | pop(v); | |
| 340 | elseif index < 0 or index > sz then | ||
| 341 | ✗ | fail(); | |
| 342 | else | ||
| 343 | 32683 | data := Mutable.access(v.data); | |
| 344 | |||
| 345 |
1/2✓ Branch 0 taken 32683 times.
✗ Branch 1 not taken.
|
473468 | for i in index:sz loop |
| 346 | 440785 | arrayUpdateNoBoundsChecking(data, i, | |
| 347 | arrayGetNoBoundsChecking(data, i + 1)); | ||
| 348 | end for; | ||
| 349 | |||
| 350 | 32683 | Mutable.update(v.size, sz - 1); | |
| 351 | end if; | ||
| 352 | end remove; | ||
| 353 | |||
| 354 | function update | ||
| 355 | "Updates the element at the given one-based index to the given value. | ||
| 356 | Fails if the index is out of bounds." | ||
| 357 | input Vector<T> v; | ||
| 358 | input Integer index; | ||
| 359 | input T value; | ||
| 360 | protected | ||
| 361 | array<T> data = Mutable.access(v.data); | ||
| 362 | Integer sz = Mutable.access(v.size); | ||
| 363 | algorithm | ||
| 364 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3030267 times.
|
3030267 | if index <= 0 or index > sz then |
| 365 | ✗ | fail(); | |
| 366 | end if; | ||
| 367 | |||
| 368 | arrayUpdateNoBoundsChecking(data, index, value); | ||
| 369 | end update; | ||
| 370 | |||
| 371 | function updateNoBounds | ||
| 372 | "Updates the element at the given one-based index to the given value without | ||
| 373 | checking if the one-based index is in bounds. This is DANGEROUS and should | ||
| 374 | only be used when the index is already known to be in bounds." | ||
| 375 | input Vector<T> v; | ||
| 376 | input Integer index; | ||
| 377 | input T value; | ||
| 378 | algorithm | ||
| 379 | 1374704 | arrayUpdateNoBoundsChecking(Mutable.access(v.data), index, value); | |
| 380 | end updateNoBounds; | ||
| 381 | |||
| 382 | function get | ||
| 383 | "Returns the value of the element at the given one-based index. | ||
| 384 | Fails if the index is out of bounds." | ||
| 385 | input Vector<T> v; | ||
| 386 | input Integer index; | ||
| 387 | output T value; | ||
| 388 | protected | ||
| 389 | array<T> data = Mutable.access(v.data); | ||
| 390 | Integer sz = Mutable.access(v.size); | ||
| 391 | algorithm | ||
| 392 |
2/2✓ Branch 0 taken 5078568 times.
✓ Branch 1 taken 17870591 times.
|
22949159 | if index <= 0 or index > sz then |
| 393 | 5078568 | fail(); | |
| 394 | end if; | ||
| 395 | |||
| 396 | 17870591 | value := arrayGetNoBoundsChecking(data, index); | |
| 397 | end get; | ||
| 398 | |||
| 399 | function getNoBounds | ||
| 400 | "Returns the value of the element at the given one-based index without | ||
| 401 | checking if the index is out of bounds. This is DANGEROUS and should only | ||
| 402 | be used when the index is already known to be in bounds." | ||
| 403 | input Vector<T> v; | ||
| 404 | input Integer index; | ||
| 405 | output T value; | ||
| 406 | algorithm | ||
| 407 | 15084667 | value := arrayGetNoBoundsChecking(Mutable.access(v.data), index); | |
| 408 | end getNoBounds; | ||
| 409 | |||
| 410 | function last | ||
| 411 | "Returns the last element in the array, or fails if the array is empty." | ||
| 412 | input Vector<T> v; | ||
| 413 | output T value; | ||
| 414 | protected | ||
| 415 | array<T> data = Mutable.access(v.data); | ||
| 416 | Integer sz = Mutable.access(v.size); | ||
| 417 | algorithm | ||
| 418 | ✗ | if sz == 0 then | |
| 419 | ✗ | fail(); | |
| 420 | end if; | ||
| 421 | |||
| 422 | ✗ | value := arrayGetNoBoundsChecking(data, sz); | |
| 423 | end last; | ||
| 424 | |||
| 425 | function size | ||
| 426 | "Returns the number of elements in the Vector." | ||
| 427 | input Vector<T> v; | ||
| 428 | output Integer sz = Mutable.access(v.size); | ||
| 429 | end size; | ||
| 430 | |||
| 431 | function capacity | ||
| 432 | "Returns the number of elements the Vector can store without having to | ||
| 433 | allocate more memory." | ||
| 434 | input Vector<T> v; | ||
| 435 | output Integer capacity = arrayLength(Mutable.access(v.data)); | ||
| 436 | end capacity; | ||
| 437 | |||
| 438 | function isEmpty | ||
| 439 | "Returns true if the Vector is empty, otherwise false." | ||
| 440 | input Vector<T> v; | ||
| 441 | output Boolean empty = Mutable.access(v.size) == 0; | ||
| 442 | end isEmpty; | ||
| 443 | |||
| 444 | function reserve | ||
| 445 | "Increases the capacity of the Vector to the given amount of elements. | ||
| 446 | Does nothing if the Vector's capacity is already large enough." | ||
| 447 | input Vector<T> v; | ||
| 448 | input Integer newCapacity; | ||
| 449 | protected | ||
| 450 | array<T> data = Mutable.access(v.data); | ||
| 451 | algorithm | ||
| 452 |
2/2✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 402 times.
|
1646 | if newCapacity > arrayLength(data) then |
| 453 | 402 | data := resizeArray(data, newCapacity); | |
| 454 | 402 | Mutable.update(v.data, data); | |
| 455 | end if; | ||
| 456 | end reserve; | ||
| 457 | |||
| 458 | function trim | ||
| 459 | "Shrinks the capacity of the Vector to the actual number of elements it contains." | ||
| 460 | input Vector<T> v; | ||
| 461 | protected | ||
| 462 | array<T> data = Mutable.access(v.data); | ||
| 463 | Integer sz = Mutable.access(v.size); | ||
| 464 | algorithm | ||
| 465 | ✗ | if sz < arrayLength(data) then | |
| 466 | ✗ | data := resizeArray(data, sz); | |
| 467 | ✗ | Mutable.update(v.data, data); | |
| 468 | end if; | ||
| 469 | end trim; | ||
| 470 | |||
| 471 | function fill | ||
| 472 | "Fills the given interval with the given value. Fails if any part of the | ||
| 473 | interval is out of bounds. Does nothing if the lower bound of the interval | ||
| 474 | is larger than the upper bound." | ||
| 475 | input Vector<T> v; | ||
| 476 | input T value; | ||
| 477 | input Integer from = 1; | ||
| 478 | input Integer to = Mutable.access(v.size); | ||
| 479 | protected | ||
| 480 | array<T> data = Mutable.access(v.data); | ||
| 481 | Integer sz = Mutable.access(v.size); | ||
| 482 | algorithm | ||
| 483 | ✗ | if from < 1 or to < 1 or from > sz or to > sz then | |
| 484 | ✗ | fail(); | |
| 485 | end if; | ||
| 486 | |||
| 487 | ✗ | for i in from:to loop | |
| 488 | arrayUpdateNoBoundsChecking(data, i, value); | ||
| 489 | end for; | ||
| 490 | end fill; | ||
| 491 | |||
| 492 | function map<OT> | ||
| 493 | "Applies a function to each element of the given Vector and creates a new | ||
| 494 | Vector from the results. If shrink is set to true then the new Vector will | ||
| 495 | only allocate enough capacity to hold the new elements, if shrink is set to | ||
| 496 | false it will keep the same capacity as the old Vector." | ||
| 497 | input Vector<T> v; | ||
| 498 | input MapFn fn; | ||
| 499 | input Boolean shrink = true; | ||
| 500 | output Vector<OT> outV; | ||
| 501 | |||
| 502 | partial function MapFn | ||
| 503 | input T value; | ||
| 504 | output OT res; | ||
| 505 | end MapFn; | ||
| 506 | protected | ||
| 507 | array<T> data = Mutable.access(v.data); | ||
| 508 | Integer sz = Mutable.access(v.size); | ||
| 509 | array<OT> new_data; | ||
| 510 | OT dummy = dummy; | ||
| 511 | algorithm | ||
| 512 | ✗ | new_data := arrayCreateNoInit(if shrink then sz else arrayLength(data), dummy); | |
| 513 | |||
| 514 | ✗ | for i in 1:sz loop | |
| 515 | ✗ | arrayUpdateNoBoundsChecking(new_data, i, fn(arrayGetNoBoundsChecking(data, i))); | |
| 516 | end for; | ||
| 517 | |||
| 518 | ✗ | outV := VECTOR(Mutable.create(new_data), Mutable.create(sz)); | |
| 519 | end map; | ||
| 520 | |||
| 521 | function mapToList<OT> | ||
| 522 | "Applies a function to each element of the given Vector and creates a new | ||
| 523 | list from the results." | ||
| 524 | input Vector<T> v; | ||
| 525 | input MapFn fn; | ||
| 526 | output list<OT> l = {}; | ||
| 527 | |||
| 528 | partial function MapFn | ||
| 529 | input T value; | ||
| 530 | output OT res; | ||
| 531 | end MapFn; | ||
| 532 | protected | ||
| 533 | array<T> data = Mutable.access(v.data); | ||
| 534 | Integer sz = Mutable.access(v.size); | ||
| 535 | algorithm | ||
| 536 | ✗ | for i in sz:-1:1 loop | |
| 537 | ✗ | l := fn(arrayGetNoBoundsChecking(data, i)) :: l; | |
| 538 | end for; | ||
| 539 | end mapToList; | ||
| 540 | |||
| 541 | function apply | ||
| 542 | "Applies the given function to each element in the Vector, changing each | ||
| 543 | element's value to the result of the call." | ||
| 544 | input Vector<T> v; | ||
| 545 | input ApplyFn fn; | ||
| 546 | |||
| 547 | partial function ApplyFn | ||
| 548 | input output T value; | ||
| 549 | end ApplyFn; | ||
| 550 | protected | ||
| 551 | array<T> data = Mutable.access(v.data); | ||
| 552 | Integer sz = Mutable.access(v.size); | ||
| 553 | algorithm | ||
| 554 |
2/2✓ Branch 0 taken 281 times.
✓ Branch 1 taken 56405 times.
|
332767 | for i in 1:sz loop |
| 555 |
2/2✓ Branch 0 taken 193918 times.
✓ Branch 1 taken 82163 times.
|
276081 | arrayUpdateNoBoundsChecking(data, i, |
| 556 | fn(arrayGetNoBoundsChecking(data, i))); | ||
| 557 | end for; | ||
| 558 | end apply; | ||
| 559 | |||
| 560 | function fold<FT> | ||
| 561 | "Applies the given function to each element in the Vector, updating the | ||
| 562 | given argument as it goes along." | ||
| 563 | input Vector<T> v; | ||
| 564 | input FoldFn fn; | ||
| 565 | input output FT arg; | ||
| 566 | |||
| 567 | partial function FoldFn | ||
| 568 | input T value; | ||
| 569 | input output FT arg; | ||
| 570 | end FoldFn; | ||
| 571 | protected | ||
| 572 | array<T> data = Mutable.access(v.data); | ||
| 573 | Integer sz = Mutable.access(v.size); | ||
| 574 | algorithm | ||
| 575 | ✗ | for i in 1:sz loop | |
| 576 | ✗ | arg := fn(arrayGetNoBoundsChecking(data, i), arg); | |
| 577 | end for; | ||
| 578 | end fold; | ||
| 579 | |||
| 580 | function find | ||
| 581 | "Returns the first element and the index of that element for which the given | ||
| 582 | function returns true, or NONE() and -1 if no such element exists." | ||
| 583 | input Vector<T> v; | ||
| 584 | input PredFn fn; | ||
| 585 | output Option<T> oe; | ||
| 586 | output Integer index; | ||
| 587 | |||
| 588 | partial function PredFn | ||
| 589 | input T e; | ||
| 590 | output Boolean res; | ||
| 591 | end PredFn; | ||
| 592 | protected | ||
| 593 | array<T> data = Mutable.access(v.data); | ||
| 594 | Integer sz = Mutable.access(v.size); | ||
| 595 | T e; | ||
| 596 | algorithm | ||
| 597 |
2/2✓ Branch 0 taken 385586 times.
✓ Branch 1 taken 162425 times.
|
4641483 | for i in 1:sz loop |
| 598 | 4135368 | e := arrayGetNoBoundsChecking(data, i); | |
| 599 | |||
| 600 |
3/4✓ Branch 0 taken 4135368 times.
✗ Branch 1 not taken.
✓ Branch 4 taken 41896 times.
✓ Branch 5 taken 4093472 times.
|
4135368 | if fn(e) then |
| 601 | oe := SOME(e); | ||
| 602 | index := i; | ||
| 603 | 41896 | return; | |
| 604 | end if; | ||
| 605 | end for; | ||
| 606 | |||
| 607 | oe := NONE(); | ||
| 608 | index := -1; | ||
| 609 | end find; | ||
| 610 | |||
| 611 | function findLast | ||
| 612 | "Returns the last element and the index of that element for which the given | ||
| 613 | function returns true, or NONE() and -1 if no such element exists." | ||
| 614 | input Vector<T> v; | ||
| 615 | input PredFn fn; | ||
| 616 | output Option<T> oe; | ||
| 617 | output Integer index; | ||
| 618 | |||
| 619 | partial function PredFn | ||
| 620 | input T e; | ||
| 621 | output Boolean res; | ||
| 622 | end PredFn; | ||
| 623 | protected | ||
| 624 | array<T> data = Mutable.access(v.data); | ||
| 625 | Integer sz = Mutable.access(v.size); | ||
| 626 | T e; | ||
| 627 | algorithm | ||
| 628 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | for i in sz:-1:1 loop |
| 629 | 9 | e := arrayGetNoBoundsChecking(data, i); | |
| 630 | |||
| 631 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 3 times.
|
9 | if fn(e) then |
| 632 | oe := SOME(e); | ||
| 633 | index := i; | ||
| 634 | 3 | return; | |
| 635 | end if; | ||
| 636 | end for; | ||
| 637 | |||
| 638 | oe := NONE(); | ||
| 639 | index := -1; | ||
| 640 | end findLast; | ||
| 641 | |||
| 642 | function findFold<FT> | ||
| 643 | "Returns the first element and the index of that element for which the given | ||
| 644 | function returns true, but proceeds to check all other for better | ||
| 645 | solutions regarding an extra argument, or NONE() and -1 if no such element exists." | ||
| 646 | input Vector<T> v; | ||
| 647 | input PredFn fn; | ||
| 648 | output Option<T> oe = NONE(); | ||
| 649 | output Integer index = -1; | ||
| 650 | input output FT arg; | ||
| 651 | |||
| 652 | partial function PredFn | ||
| 653 | input T e; | ||
| 654 | output Boolean res; | ||
| 655 | input output FT arg; | ||
| 656 | end PredFn; | ||
| 657 | protected | ||
| 658 | array<T> data = Mutable.access(v.data); | ||
| 659 | Integer sz = Mutable.access(v.size); | ||
| 660 | T e; | ||
| 661 | Boolean res; | ||
| 662 | algorithm | ||
| 663 | ✗ | for i in 1:sz loop | |
| 664 | ✗ | e := arrayGetNoBoundsChecking(data, i); | |
| 665 | |||
| 666 | ✗ | (res, arg) := fn(e, arg); | |
| 667 | ✗ | if res then | |
| 668 | oe := SOME(e); | ||
| 669 | index := i; | ||
| 670 | end if; | ||
| 671 | end for; | ||
| 672 | end findFold; | ||
| 673 | |||
| 674 | function all | ||
| 675 | "Returns true if the given function returns true for all elements in the | ||
| 676 | Vector, otherwise false." | ||
| 677 | input Vector<T> v; | ||
| 678 | input PredFn fn; | ||
| 679 | output Boolean res; | ||
| 680 | |||
| 681 | partial function PredFn | ||
| 682 | input T e; | ||
| 683 | output Boolean res; | ||
| 684 | end PredFn; | ||
| 685 | protected | ||
| 686 | array<T> data = Mutable.access(v.data); | ||
| 687 | algorithm | ||
| 688 |
1/2✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
|
1424 | for i in 1:Mutable.access(v.size) loop |
| 689 |
3/4✓ Branch 0 taken 1388 times.
✗ Branch 1 not taken.
✓ Branch 4 taken 60 times.
✓ Branch 5 taken 1328 times.
|
1388 | if not fn(arrayGetNoBoundsChecking(data, i)) then |
| 690 | res := false; | ||
| 691 | 60 | return; | |
| 692 | end if; | ||
| 693 | end for; | ||
| 694 | |||
| 695 | res := true; | ||
| 696 | end all; | ||
| 697 | |||
| 698 | function any | ||
| 699 | "Returns true if the given function returns true for any element in the | ||
| 700 | Vector, otherwise false." | ||
| 701 | input Vector<T> v; | ||
| 702 | input PredFn fn; | ||
| 703 | output Boolean res; | ||
| 704 | |||
| 705 | partial function PredFn | ||
| 706 | input T e; | ||
| 707 | output Boolean res; | ||
| 708 | end PredFn; | ||
| 709 | protected | ||
| 710 | array<T> data = Mutable.access(v.data); | ||
| 711 | algorithm | ||
| 712 | ✗ | for i in 1:Mutable.access(v.size) loop | |
| 713 | ✗ | if fn(arrayGetNoBoundsChecking(data, i)) then | |
| 714 | res := true; | ||
| 715 | ✗ | return; | |
| 716 | end if; | ||
| 717 | end for; | ||
| 718 | |||
| 719 | res := false; | ||
| 720 | end any; | ||
| 721 | |||
| 722 | function none | ||
| 723 | "Returns true if the given function returns true for none of the elements in | ||
| 724 | the Vector, otherwise false." | ||
| 725 | input Vector<T> v; | ||
| 726 | input PredFn fn; | ||
| 727 | output Boolean res; | ||
| 728 | |||
| 729 | partial function PredFn | ||
| 730 | input T e; | ||
| 731 | output Boolean res; | ||
| 732 | end PredFn; | ||
| 733 | protected | ||
| 734 | array<T> data = Mutable.access(v.data); | ||
| 735 | algorithm | ||
| 736 |
2/2✓ Branch 1 taken 169592 times.
✓ Branch 2 taken 33455 times.
|
203047 | for i in 1:Mutable.access(v.size) loop |
| 737 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 169592 times.
✓ Branch 4 taken 169592 times.
✗ Branch 5 not taken.
|
169592 | if fn(arrayGetNoBoundsChecking(data, i)) then |
| 738 | res := false; | ||
| 739 | 169592 | return; | |
| 740 | end if; | ||
| 741 | end for; | ||
| 742 | |||
| 743 | res := true; | ||
| 744 | end none; | ||
| 745 | |||
| 746 | function copy | ||
| 747 | "Creates a copy of the given Vector." | ||
| 748 | input Vector<T> v; | ||
| 749 | output Vector<T> c; | ||
| 750 | protected | ||
| 751 | array<T> data = Mutable.access(v.data); | ||
| 752 | Integer sz = Mutable.access(v.size); | ||
| 753 | algorithm | ||
| 754 | 11736 | c := VECTOR(Mutable.create(arrayCopy(data)), Mutable.create(sz)); | |
| 755 | end copy; | ||
| 756 | |||
| 757 | function deepCopy | ||
| 758 | "Creates a deep copy of the given Vector using the given copy function." | ||
| 759 | input Vector<T> v; | ||
| 760 | input CopyFn fn; | ||
| 761 | output Vector<T> c; | ||
| 762 | |||
| 763 | partial function CopyFn | ||
| 764 | input output T value; | ||
| 765 | end CopyFn; | ||
| 766 | protected | ||
| 767 | array<T> data = Mutable.access(v.data); | ||
| 768 | Integer sz = Mutable.access(v.size); | ||
| 769 | algorithm | ||
| 770 | ✗ | data := arrayCopy(data); | |
| 771 | |||
| 772 | ✗ | for i in 1:arrayLength(data) loop | |
| 773 | ✗ | arrayUpdateNoBoundsChecking(data, i, fn(arrayGetNoBoundsChecking(data, i))); | |
| 774 | end for; | ||
| 775 | |||
| 776 | ✗ | c := VECTOR(Mutable.create(data), Mutable.create(sz)); | |
| 777 | end deepCopy; | ||
| 778 | |||
| 779 | function swap | ||
| 780 | "Swaps the contents of two Vectors." | ||
| 781 | input Vector<T> v1; | ||
| 782 | input Vector<T> v2; | ||
| 783 | protected | ||
| 784 | array<T> data1 = Mutable.access(v1.data); | ||
| 785 | array<T> data2 = Mutable.access(v2.data); | ||
| 786 | Integer sz1 = Mutable.access(v1.size); | ||
| 787 | Integer sz2 = Mutable.access(v2.size); | ||
| 788 | algorithm | ||
| 789 | 25 | Mutable.update(v1.data, data2); | |
| 790 | 25 | Mutable.update(v2.data, data1); | |
| 791 | 25 | Mutable.update(v1.size, sz2); | |
| 792 | 25 | Mutable.update(v2.size, sz1); | |
| 793 | end swap; | ||
| 794 | |||
| 795 | function toString | ||
| 796 | input Vector<T> v; | ||
| 797 | input StringFn stringFn; | ||
| 798 | input String strBegin = "["; | ||
| 799 | input String delim = ", "; | ||
| 800 | input String strEnd = "]"; | ||
| 801 | output String str; | ||
| 802 | |||
| 803 | partial function StringFn | ||
| 804 | input T e; | ||
| 805 | output String str; | ||
| 806 | end StringFn; | ||
| 807 | algorithm | ||
| 808 | ✗ | str := strBegin + stringDelimitList(list(stringFn(e) for e in toArray(v)), delim) + strEnd; | |
| 809 | end toString; | ||
| 810 | |||
| 811 | protected | ||
| 812 | function resizeArray | ||
| 813 | "Allocates a new array with the given size, and copies elements from the given | ||
| 814 | array to the new array until either all elements have been copied or the new | ||
| 815 | array has been filled." | ||
| 816 | input array<T> arr; | ||
| 817 | input Integer newSize; | ||
| 818 | output array<T> outArr; | ||
| 819 | protected | ||
| 820 | T dummy = dummy; | ||
| 821 | algorithm | ||
| 822 | 2905407 | outArr := arrayCreateNoInit(newSize, dummy); | |
| 823 | |||
| 824 |
2/2✓ Branch 0 taken 941346 times.
✓ Branch 1 taken 1964061 times.
|
15644785 | for i in 1:min(newSize, arrayLength(arr)) loop |
| 825 | 12739378 | arrayUpdateNoBoundsChecking(outArr, i, arrayGetNoBoundsChecking(arr, i)); | |
| 826 | end for; | ||
| 827 | end resizeArray; | ||
| 828 | |||
| 829 | function reserveCapacity | ||
| 830 | input Vector<T> v; | ||
| 831 | input Integer newSize; | ||
| 832 | output array<T> data = Mutable.access(v.data); | ||
| 833 | protected | ||
| 834 | Integer cap = arrayLength(data); | ||
| 835 | algorithm | ||
| 836 |
2/2✓ Branch 0 taken 6682554 times.
✓ Branch 1 taken 2905005 times.
|
9587559 | if newSize > cap then |
| 837 | cap := max(cap, 1); | ||
| 838 | |||
| 839 |
2/2✓ Branch 0 taken 2242654 times.
✓ Branch 1 taken 2905005 times.
|
5147659 | while newSize > cap loop |
| 840 | 2242654 | cap := cap * 2; | |
| 841 | end while; | ||
| 842 | |||
| 843 | 2905005 | data := resizeArray(Mutable.access(v.data), cap); | |
| 844 | 2905005 | Mutable.update(v.data, data); | |
| 845 | end if; | ||
| 846 | end reserveCapacity; | ||
| 847 | |||
| 848 | annotation(__OpenModelica_Interface="util"); | ||
| 849 | end Vector; | ||
| 850 |