OMCompiler/SimulationRuntime/cpp/Core/Math/ArraySlice.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * This file belongs to the OpenModelica Run-Time System | ||
| 3 | * | ||
| 4 | * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC), c/o Linköpings | ||
| 5 | * universitet, Department of Computer and Information Science, SE-58183 Linköping, Sweden. All rights | ||
| 6 | * reserved. | ||
| 7 | * | ||
| 8 | * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF THE BSD NEW LICENSE OR THE | ||
| 9 | * AGPL VERSION 3 LICENSE OR THE OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8. ANY | ||
| 10 | * USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES RECIPIENT'S | ||
| 11 | * ACCEPTANCE OF THE BSD NEW LICENSE OR THE OSMC PUBLIC LICENSE OR THE AGPL | ||
| 12 | * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. | ||
| 13 | * | ||
| 14 | * The OpenModelica software and the OSMC (Open Source Modelica Consortium) Public License | ||
| 15 | * (OSMC-PL) are obtained from OSMC, either from the above address, from the URLs: | ||
| 16 | * http://www.openmodelica.org or https://github.com/OpenModelica/ or | ||
| 17 | * http://www.ida.liu.se/projects/OpenModelica, and in the OpenModelica distribution. GNU | ||
| 18 | * AGPL version 3 is obtained from: https://www.gnu.org/licenses/licenses.html#GPL. The BSD NEW | ||
| 19 | * License is obtained from: http://www.opensource.org/licenses/BSD-3-Clause. | ||
| 20 | * | ||
| 21 | * This program is distributed WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY | ||
| 23 | * SET FORTH IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF | ||
| 24 | * OSMC-PL. | ||
| 25 | * | ||
| 26 | */ | ||
| 27 | |||
| 28 | #pragma once | ||
| 29 | |||
| 30 | /* Implement Modelica array slices. */ | ||
| 31 | |||
| 32 | #include "Array.h" | ||
| 33 | /** @addtogroup math | ||
| 34 | * @{ | ||
| 35 | */ | ||
| 36 | |||
| 37 | /** | ||
| 38 | * Modelica slice. | ||
| 39 | * Defined by an index vector iset != NULL or by start:stop or start:step:stop, | ||
| 40 | * start == stop and step == 0 meaning reduction of dimension, | ||
| 41 | * is_stop_end marking stop == end. | ||
| 42 | */ | ||
| 43 | class Slice { | ||
| 44 | public: | ||
| 45 | // all indices | ||
| 46 | ✗ | Slice() { | |
| 47 | ✗ | start = 1; | |
| 48 | ✗ | step = 1; | |
| 49 | ✗ | stop = 0; | |
| 50 | ✗ | is_stop_end = true; | |
| 51 | ✗ | iset = NULL; | |
| 52 | } | ||
| 53 | |||
| 54 | // one index (reduction) | ||
| 55 | Slice(int index) { | ||
| 56 | start = index; | ||
| 57 | step = 0; | ||
| 58 | stop = index; | ||
| 59 | is_stop_end = false; | ||
| 60 | iset = NULL; | ||
| 61 | } | ||
| 62 | |||
| 63 | Slice(int start, int stop) { | ||
| 64 | this->start = start; | ||
| 65 | step = 1; | ||
| 66 | this->stop = stop; | ||
| 67 | is_stop_end = false; | ||
| 68 | iset = NULL; | ||
| 69 | } | ||
| 70 | |||
| 71 | Slice(int start, int step, int stop) { | ||
| 72 | this->start = start; | ||
| 73 | this->step = step; | ||
| 74 | this->stop = stop; | ||
| 75 | is_stop_end = false; | ||
| 76 | iset = NULL; | ||
| 77 | } | ||
| 78 | |||
| 79 | // index set | ||
| 80 | Slice(const BaseArray<int> &indices) { | ||
| 81 | start = 0; | ||
| 82 | step = 0; | ||
| 83 | stop = 0; | ||
| 84 | is_stop_end = false; | ||
| 85 | if (indices.getNumDims() != 1) | ||
| 86 | throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION, | ||
| 87 | "Slice requires an index vector"); | ||
| 88 | // store pointer as indices should live long enough in a Modelica model | ||
| 89 | iset = &indices; | ||
| 90 | } | ||
| 91 | |||
| 92 | int start; | ||
| 93 | int step; | ||
| 94 | int stop; | ||
| 95 | bool is_stop_end; | ||
| 96 | const BaseArray<int> *iset; | ||
| 97 | }; | ||
| 98 | |||
| 99 | /** | ||
| 100 | * Multi-dimensional array slice holding a const reference to a BaseArray. | ||
| 101 | */ | ||
| 102 | template<class T> | ||
| 103 | class ArraySliceConst: public BaseArray<T> { | ||
| 104 | public: | ||
| 105 | ✗ | ArraySliceConst(const BaseArray<T> &baseArray, const vector<Slice> &slice) | |
| 106 | : BaseArray<T>(baseArray.isStatic(), false) | ||
| 107 | ✗ | , _baseArray(baseArray) | |
| 108 | ✗ | , _isets(baseArray.getNumDims()) | |
| 109 | ✗ | , _idxs(baseArray.getNumDims()) | |
| 110 | ✗ | , _baseReduction(baseArray.getNumDims()) | |
| 111 | ✗ | , _baseIdx(baseArray.getNumDims()) | |
| 112 | ✗ | , _tmp_data(NULL) { | |
| 113 | |||
| 114 | ✗ | if (baseArray.getNumDims() < slice.size()) | |
| 115 | ✗ | throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION, | |
| 116 | "Wrong slices exceeding array dimensions"); | ||
| 117 | // create an explicit index set per dimension, | ||
| 118 | // except for all indices that are indicated with an empty index set | ||
| 119 | size_t dim, size; | ||
| 120 | vector<Slice>::const_iterator sit; | ||
| 121 | vector< vector<size_t> >::iterator dit = _idxs.begin(); | ||
| 122 | ✗ | for (dim = 1, sit = slice.begin(); sit != slice.end(); dim++, sit++) { | |
| 123 | ✗ | if (sit->iset != NULL) { | |
| 124 | ✗ | _isets[dim - 1] = sit->iset; | |
| 125 | ✗ | size = sit->iset->getNumElems(); | |
| 126 | } | ||
| 127 | else { | ||
| 128 | ✗ | _isets[dim - 1] = NULL; | |
| 129 | ✗ | int maxIndex = baseArray.getDim(dim); | |
| 130 | ✗ | int start = sit->start; | |
| 131 | ✗ | int step = sit->step; | |
| 132 | ✗ | int stop = sit->is_stop_end? maxIndex: sit->stop; | |
| 133 | ✗ | size = step == 0? 1: std::max(0, (stop - start) / step + 1); | |
| 134 | ✗ | if (size > 0 && (start > maxIndex || stop > maxIndex)) | |
| 135 | ✗ | throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION, | |
| 136 | "Wrong slice exceeding array size"); | ||
| 137 | ✗ | if (start != 1 || step != 1 || stop != maxIndex) { | |
| 138 | // only fill non-trivial _idxs if this is not WHOLEDIM | ||
| 139 | ✗ | for (int i = 0; i < size; i++) | |
| 140 | ✗ | dit->push_back(start + i * step); | |
| 141 | } | ||
| 142 | } | ||
| 143 | ✗ | if (sit->iset == NULL && size == 1 && sit->step == 0) { | |
| 144 | ✗ | _baseReduction[dim - 1] = true; | |
| 145 | // preset constant _baseIdx in case of reduction | ||
| 146 | ✗ | _baseIdx[dim - 1] = sit->iset != NULL? (*_isets[dim - 1])(1): (*dit)[0]; | |
| 147 | } | ||
| 148 | else { | ||
| 149 | ✗ | _baseReduction[dim - 1] = false; | |
| 150 | ✗ | if (size == 0) | |
| 151 | ✗ | _baseIdx[dim - 1] = 0; // mark empty dimension to distinguish it from WHOLEDIM | |
| 152 | else | ||
| 153 | ✗ | _baseIdx[dim - 1] = 1; // mark regular case with a positive value | |
| 154 | // store dimension of array slice | ||
| 155 | ✗ | _dims.push_back(size); | |
| 156 | } | ||
| 157 | dit++; | ||
| 158 | } | ||
| 159 | // use all indices of remaining dims | ||
| 160 | ✗ | for (; dim <= baseArray.getNumDims(); dim++) { | |
| 161 | ✗ | _isets[dim - 1] = NULL; | |
| 162 | _baseReduction[dim - 1] = false; | ||
| 163 | ✗ | _baseIdx[dim - 1] = 1; // mark regular case with positive value | |
| 164 | ✗ | _dims.push_back(_baseArray.getDim(dim)); | |
| 165 | } | ||
| 166 | ✗ | } | |
| 167 | |||
| 168 | ✗ | virtual ~ArraySliceConst() { | |
| 169 | ✗ | if (_tmp_data != NULL) | |
| 170 | ✗ | delete [] _tmp_data; | |
| 171 | ✗ | } | |
| 172 | |||
| 173 | ✗ | virtual const T& operator()(const vector<size_t> &idx) const { | |
| 174 | ✗ | return _baseArray(baseIdx(idx.size(), &idx[0])); | |
| 175 | } | ||
| 176 | |||
| 177 | ✗ | virtual T& operator()(const vector<size_t> &idx) { | |
| 178 | ✗ | throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION, | |
| 179 | "Can't write to ArraySliceConst"); | ||
| 180 | } | ||
| 181 | |||
| 182 | ✗ | virtual void assign(const T* data) { | |
| 183 | ✗ | throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION, | |
| 184 | "Can't assign data to ArraySliceConst"); | ||
| 185 | } | ||
| 186 | |||
| 187 | ✗ | virtual void assign(const BaseArray<T>& otherArray) { | |
| 188 | ✗ | throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION, | |
| 189 | "Can't assign array to ArraySliceConst"); | ||
| 190 | } | ||
| 191 | |||
| 192 | ✗ | virtual void assign(const T& value) { | |
| 193 | ✗ | throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION, | |
| 194 | "Can't assign value to ArraySliceConst"); | ||
| 195 | } | ||
| 196 | |||
| 197 | ✗ | virtual std::vector<size_t> getDims() const { | |
| 198 | ✗ | return _dims; | |
| 199 | } | ||
| 200 | |||
| 201 | ✗ | virtual int getDim(size_t sliceDim) const { | |
| 202 | ✗ | return (int)_dims[sliceDim - 1]; | |
| 203 | } | ||
| 204 | |||
| 205 | ✗ | virtual T* getData() { | |
| 206 | ✗ | throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION, | |
| 207 | "Can't get pointer to write to ArraySlice"); | ||
| 208 | } | ||
| 209 | |||
| 210 | ✗ | virtual void getDataCopy(T data[], size_t n) const { | |
| 211 | ✗ | if (n != getNumElems()) | |
| 212 | ✗ | throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION, | |
| 213 | "Wrong number of elements in getDataCopy"); | ||
| 214 | ✗ | if (n > 0) { | |
| 215 | ✗ | const T* base_data = _baseArray.getData(); | |
| 216 | ✗ | if (base_data <= data && data < base_data + n) { | |
| 217 | // in-situ access requires an internal copy to avoid side effects, | ||
| 218 | // e.g. v = v[n:-1:1] | ||
| 219 | ✗ | const T* slice_data = getData(); | |
| 220 | std::copy(slice_data, slice_data + n, data); | ||
| 221 | } | ||
| 222 | else | ||
| 223 | // direct access | ||
| 224 | ✗ | getDataDim(_idxs.size(), data); | |
| 225 | } | ||
| 226 | ✗ | } | |
| 227 | |||
| 228 | ✗ | virtual const T* getData() const { | |
| 229 | ✗ | if (_tmp_data == NULL) | |
| 230 | // allocate on first use | ||
| 231 | ✗ | _tmp_data = new T [getNumElems()]; | |
| 232 | ✗ | getDataDim(_idxs.size(), _tmp_data); | |
| 233 | ✗ | return _tmp_data; | |
| 234 | } | ||
| 235 | |||
| 236 | ✗ | virtual size_t getNumElems() const { | |
| 237 | return std::accumulate(_dims.begin(), _dims.end(), | ||
| 238 | ✗ | 1, std::multiplies<size_t>()); | |
| 239 | } | ||
| 240 | |||
| 241 | ✗ | virtual size_t getNumDims() const { | |
| 242 | ✗ | return _dims.size(); | |
| 243 | } | ||
| 244 | |||
| 245 | ✗ | virtual void setDims(const std::vector<size_t> &v) { | |
| 246 | ✗ | throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION, | |
| 247 | "Can't set dims of ArraySlice"); | ||
| 248 | } | ||
| 249 | |||
| 250 | ✗ | virtual void resize(const std::vector<size_t> &dims) { | |
| 251 | ✗ | throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION, | |
| 252 | "Can't resize ArraySlice"); | ||
| 253 | } | ||
| 254 | |||
| 255 | ✗ | virtual const T& operator()(size_t i) const { | |
| 256 | ✗ | return _baseArray(baseIdx(1, &i)); | |
| 257 | } | ||
| 258 | |||
| 259 | ✗ | virtual const T& operator()(size_t i, size_t j) const { | |
| 260 | ✗ | size_t idx[] = {i, j}; | |
| 261 | ✗ | return _baseArray(baseIdx(2, idx)); | |
| 262 | } | ||
| 263 | |||
| 264 | ✗ | virtual const T& operator()(size_t i, size_t j, size_t k) const { | |
| 265 | ✗ | size_t idx[] = {i, j, k}; | |
| 266 | ✗ | return _baseArray(baseIdx(3, idx)); | |
| 267 | } | ||
| 268 | |||
| 269 | ✗ | virtual const T& operator()(size_t i, size_t j, size_t k, size_t l) const { | |
| 270 | ✗ | size_t idx[] = {i, j, k, l}; | |
| 271 | ✗ | return _baseArray(baseIdx(4, idx)); | |
| 272 | } | ||
| 273 | |||
| 274 | ✗ | virtual const T& operator()(size_t i, size_t j, size_t k, size_t l, size_t m) const { | |
| 275 | ✗ | size_t idx[] = {i, j, k, l, m}; | |
| 276 | ✗ | return _baseArray(baseIdx(5, idx)); | |
| 277 | } | ||
| 278 | |||
| 279 | ✗ | virtual const T& operator()(size_t i, size_t j, size_t k, size_t l, size_t m, size_t n) const { | |
| 280 | ✗ | size_t idx[] = {i, j, k, l, m, n}; | |
| 281 | ✗ | return _baseArray(baseIdx(6, idx)); | |
| 282 | } | ||
| 283 | |||
| 284 | protected: | ||
| 285 | const BaseArray<T> &_baseArray; // underlying array | ||
| 286 | vector<const BaseArray<int>*> _isets; // given index sets per dimension | ||
| 287 | vector< vector<size_t> > _idxs; // created index sets per dimension | ||
| 288 | vector<size_t> _dims; // dimensions of array slice | ||
| 289 | vector<bool> _baseReduction; // mark reduced dimensions to distinguish them from size == 1 | ||
| 290 | mutable vector<size_t> _baseIdx; // idx into underlying array | ||
| 291 | mutable T *_tmp_data; // storage for const T* getData() | ||
| 292 | |||
| 293 | /** | ||
| 294 | * returns idx vector to access an element | ||
| 295 | */ | ||
| 296 | ✗ | const vector<size_t> &baseIdx(size_t ndims, const size_t idx[]) const { | |
| 297 | ✗ | if (ndims != _dims.size()) | |
| 298 | ✗ | throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION, | |
| 299 | "Wrong dimensions accessing ArraySlice"); | ||
| 300 | size_t dim, size; | ||
| 301 | const BaseArray<int> *iset; | ||
| 302 | vector< vector<size_t> >::const_iterator dit; | ||
| 303 | ✗ | for (dim = 1, dit = _idxs.begin(); dit != _idxs.end(); dim++, dit++) { | |
| 304 | ✗ | if (_baseReduction[dim - 1]) | |
| 305 | // preset base index in case of reduction | ||
| 306 | ✗ | continue; | |
| 307 | ✗ | iset = _isets[dim - 1]; | |
| 308 | ✗ | size = iset? iset->getNumElems(): dit->size(); | |
| 309 | ✗ | switch (size) { | |
| 310 | ✗ | case 0: | |
| 311 | ✗ | if (_baseIdx[dim - 1] > 0) | |
| 312 | // all indices | ||
| 313 | ✗ | _baseIdx[dim - 1] = *idx++; | |
| 314 | else | ||
| 315 | ✗ | throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION, | |
| 316 | "Access to empty ArraySlice"); | ||
| 317 | ✗ | break; | |
| 318 | ✗ | default: | |
| 319 | // regular index mapping | ||
| 320 | ✗ | _baseIdx[dim - 1] = iset? (*iset)(*idx++): (*dit)[*idx++ - 1]; | |
| 321 | } | ||
| 322 | } | ||
| 323 | ✗ | return _baseIdx; | |
| 324 | } | ||
| 325 | |||
| 326 | /** | ||
| 327 | * recursive method for reading raw data | ||
| 328 | */ | ||
| 329 | ✗ | size_t getDataDim(size_t dim, T* data) const { | |
| 330 | size_t processed = 0; | ||
| 331 | ✗ | const BaseArray<int> *iset = _isets[dim - 1]; | |
| 332 | ✗ | size_t size = iset? iset->getNumElems(): _idxs[dim - 1].size(); | |
| 333 | ✗ | if (size == 0 && _baseIdx[dim - 1] > 0) | |
| 334 | ✗ | size = _baseArray.getDim(dim); | |
| 335 | ✗ | for (size_t i = 1; i <= size; i++) { | |
| 336 | ✗ | if (iset) | |
| 337 | ✗ | _baseIdx[dim - 1] = iset->getNumElems() > 0? (*iset)(i): i; | |
| 338 | else | ||
| 339 | ✗ | _baseIdx[dim - 1] = _idxs[dim - 1].size() > 0? _idxs[dim - 1][i - 1]: i; | |
| 340 | ✗ | if (dim > 1) | |
| 341 | ✗ | processed += getDataDim(dim - 1, data + processed); | |
| 342 | else | ||
| 343 | ✗ | data[processed++] = _baseArray(_baseIdx); | |
| 344 | } | ||
| 345 | ✗ | return processed; | |
| 346 | } | ||
| 347 | }; | ||
| 348 | |||
| 349 | /** | ||
| 350 | * Multi-dimensional array slice extending ArraySliceConst with write access | ||
| 351 | */ | ||
| 352 | template<class T> | ||
| 353 | ✗ | class ArraySlice: public ArraySliceConst<T> { | |
| 354 | public: | ||
| 355 | ✗ | ArraySlice(BaseArray<T> &baseArray, const vector<Slice> &slice) | |
| 356 | : ArraySliceConst<T>(baseArray, slice) | ||
| 357 | ✗ | , _baseArray(baseArray) | |
| 358 | ✗ | , _idxs(ArraySliceConst<T>::_idxs) | |
| 359 | ✗ | , _baseIdx(ArraySliceConst<T>::_baseIdx) { | |
| 360 | } | ||
| 361 | |||
| 362 | ArraySlice<T>& operator=(const ArraySlice<T>& b) | ||
| 363 | { | ||
| 364 | this->assign(b); | ||
| 365 | return *this; | ||
| 366 | } | ||
| 367 | |||
| 368 | ArraySlice<T>& operator=(const BaseArray<T>& b) | ||
| 369 | { | ||
| 370 | this->assign(b); | ||
| 371 | return *this; | ||
| 372 | } | ||
| 373 | |||
| 374 | ✗ | virtual T& operator()(const vector<size_t> &idx) { | |
| 375 | ✗ | return _baseArray(ArraySliceConst<T>::baseIdx(idx.size(), &idx[0])); | |
| 376 | } | ||
| 377 | |||
| 378 | ✗ | virtual void assign(const T* data) { | |
| 379 | ✗ | setDataDim(_idxs.size(), data); | |
| 380 | ✗ | } | |
| 381 | |||
| 382 | ✗ | virtual void assign(const BaseArray<T>& otherArray) { | |
| 383 | ✗ | setDataDim(_idxs.size(), otherArray.getData()); | |
| 384 | ✗ | } | |
| 385 | |||
| 386 | ✗ | virtual void assign(const T& value) { | |
| 387 | ✗ | setEachDim(_idxs.size(), value); | |
| 388 | ✗ | } | |
| 389 | |||
| 390 | ✗ | virtual T& operator()(size_t i) { | |
| 391 | ✗ | return _baseArray(ArraySliceConst<T>::baseIdx(1, &i)); | |
| 392 | } | ||
| 393 | |||
| 394 | ✗ | virtual T& operator()(size_t i, size_t j) { | |
| 395 | ✗ | size_t idx[] = {i, j}; | |
| 396 | ✗ | return _baseArray(ArraySliceConst<T>::baseIdx(2, idx)); | |
| 397 | } | ||
| 398 | |||
| 399 | ✗ | virtual T& operator()(size_t i, size_t j, size_t k) { | |
| 400 | ✗ | size_t idx[] = {i, j, k}; | |
| 401 | ✗ | return _baseArray(ArraySliceConst<T>::baseIdx(3, idx)); | |
| 402 | } | ||
| 403 | |||
| 404 | ✗ | virtual T& operator()(size_t i, size_t j, size_t k, size_t l) { | |
| 405 | ✗ | size_t idx[] = {i, j, k, l}; | |
| 406 | ✗ | return _baseArray(ArraySliceConst<T>::baseIdx(4, idx)); | |
| 407 | } | ||
| 408 | |||
| 409 | ✗ | virtual T& operator()(size_t i, size_t j, size_t k, size_t l, size_t m) { | |
| 410 | ✗ | size_t idx[] = {i, j, k, l, m}; | |
| 411 | ✗ | return _baseArray(ArraySliceConst<T>::baseIdx(5, idx)); | |
| 412 | } | ||
| 413 | |||
| 414 | ✗ | virtual T& operator()(size_t i, size_t j, size_t k, size_t l, size_t m, size_t n) { | |
| 415 | ✗ | size_t idx[] = {i, j, k, l, m, n}; | |
| 416 | ✗ | return _baseArray(ArraySliceConst<T>::baseIdx(6, idx)); | |
| 417 | } | ||
| 418 | |||
| 419 | protected: | ||
| 420 | BaseArray<T> &_baseArray; // underlying array | ||
| 421 | vector< vector<size_t> > &_idxs; // reference to index set of ArraySliceConst | ||
| 422 | vector<size_t> &_baseIdx; // reference to idx into underlying array | ||
| 423 | |||
| 424 | /** | ||
| 425 | * recursive method for muli-dimensional assignment of raw data | ||
| 426 | */ | ||
| 427 | ✗ | size_t setDataDim(size_t dim, const T* data) { | |
| 428 | size_t processed = 0; | ||
| 429 | ✗ | const BaseArray<int> *iset = ArraySliceConst<T>::_isets[dim - 1]; | |
| 430 | ✗ | size_t size = iset? iset->getNumElems(): _idxs[dim - 1].size(); | |
| 431 | ✗ | if (size == 0 && _baseIdx[dim - 1] > 0) | |
| 432 | ✗ | size = _baseArray.getDim(dim); | |
| 433 | ✗ | for (size_t i = 1; i <= size; i++) { | |
| 434 | ✗ | if (iset) | |
| 435 | ✗ | _baseIdx[dim - 1] = iset->getNumElems() > 0? (*iset)(i): i; | |
| 436 | else | ||
| 437 | ✗ | _baseIdx[dim - 1] = _idxs[dim - 1].size() > 0? _idxs[dim - 1][i - 1]: i; | |
| 438 | ✗ | if (dim > 1) | |
| 439 | ✗ | processed += setDataDim(dim - 1, data + processed); | |
| 440 | else | ||
| 441 | ✗ | _baseArray(_baseIdx) = data[processed++]; | |
| 442 | } | ||
| 443 | ✗ | return processed; | |
| 444 | } | ||
| 445 | |||
| 446 | /** | ||
| 447 | * recursive method for muli-dimensional fill of each element | ||
| 448 | */ | ||
| 449 | ✗ | void setEachDim(size_t dim, const T& value) { | |
| 450 | ✗ | const BaseArray<int> *iset = ArraySliceConst<T>::_isets[dim - 1]; | |
| 451 | ✗ | size_t size = iset? iset->getNumElems(): _idxs[dim - 1].size(); | |
| 452 | ✗ | if (size == 0 && _baseIdx[dim - 1] > 0) | |
| 453 | ✗ | size = _baseArray.getDim(dim); | |
| 454 | ✗ | for (size_t i = 1; i <= size; i++) { | |
| 455 | ✗ | if (iset) | |
| 456 | ✗ | _baseIdx[dim - 1] = iset->getNumElems() > 0? (*iset)(i): i; | |
| 457 | else | ||
| 458 | ✗ | _baseIdx[dim - 1] = _idxs[dim - 1].size() > 0? _idxs[dim - 1][i - 1]: i; | |
| 459 | ✗ | if (dim > 1) | |
| 460 | ✗ | setEachDim(dim - 1, value); | |
| 461 | else | ||
| 462 | ✗ | _baseArray(_baseIdx) = value; | |
| 463 | } | ||
| 464 | ✗ | } | |
| 465 | }; | ||
| 466 | /** @} */ // end of math | ||
| 467 |