+
+/**
+ * For a 2- or 3-level SkyLine array, return a copy of the absolute pack with given identifier.
+ */
+void MEDCouplingSkyLineArray::getSimplePackSafe(const int absolutePackId, std::vector<int> & pack) const
+{
+ if(absolutePackId < 0 || absolutePackId >= _index->getNbOfElems())
+ throw INTERP_KERNEL::Exception("MEDCouplingSkyLineArray::getPackSafe: invalid index!");
+ const int * iP(_index->begin()), *vP(_values->begin());
+ int sz = iP[absolutePackId+1]-iP[absolutePackId];
+ pack.resize(sz);
+ std::copy(vP+iP[absolutePackId], vP+iP[absolutePackId+1],pack.begin());
+}
+
+/**
+ * Same as getPackSafe, but directly returns a pointer to the internal data with the size of the pack.
+ */
+const int * MEDCouplingSkyLineArray::getSimplePackSafePtr(const int absolutePackId, int & packSize) const
+{
+ if(absolutePackId < 0 || absolutePackId >= _index->getNbOfElems())
+ throw INTERP_KERNEL::Exception("MEDCouplingSkyLineArray::getPackSafe: invalid index!");
+ const int * iP(_index->begin()), *vP(_values->begin());
+ packSize = iP[absolutePackId+1]-iP[absolutePackId];
+ return vP+iP[absolutePackId];
+}
+
+
+/**!
+ * For each given super-pack ID, provide the sub-index of the first matching pack. If no matching pack is found for the
+ * given super-pack -1 is returned.
+ * \param[in] superPackIndices the list of super-packs that should be inspected
+ * \param[in] packBg the pack that the function is looking for in each of the provided super-pack
+ * \param[in] packEnd the pack that the function is looking for in each of the provided super-pack
+ * \param[out] a vector of int, having the same size as superPackIndices and containing for each inspected super-pack
+ * the index of the first matching pack, or -1 if none found.
+ */
+void MEDCouplingSkyLineArray::findPackIds(const std::vector<int> & superPackIndices,
+ const int *packBg, const int *packEnd,
+ std::vector<int>& out) const
+{
+ using namespace std;
+
+ checkSuperIndex("findPackIds");
+
+ int packSz = std::distance(packBg, packEnd);
+ if (!packSz)
+ throw INTERP_KERNEL::Exception("MEDCouplingSkyLineArray::findPackIds: void pack!");
+
+ out.resize(superPackIndices.size());
+ int i = 0;
+ const int * siP(_super_index->begin()), * iP(_index->begin()), *vP(_values->begin());
+ for(vector<int>::const_iterator it=superPackIndices.begin(); it!=superPackIndices.end(); ++it, i++)
+ {
+ out[i] = -1;
+ const int sPackIdx = *it;
+ // for each pack
+ for (int idx=siP[sPackIdx], j=0; idx < siP[sPackIdx+1]; idx++, j++)
+ {
+ if (packSz == (iP[idx+1] - iP[idx]))
+ if (equal(&vP[iP[idx]], &vP[iP[idx+1]], packBg))
+ {
+ out[i] = j;
+ break;
+ }
+ }
+ }
+}
+
+/**!
+ * Delete pack number 'idx' in super-pack number 'superIdx'.
+ * \param[in] superIdx is the super-pack number
+ * \param[in] idx is the pack index inside the super-pack 'superIdx'.
+ */
+void MEDCouplingSkyLineArray::deletePack(const int superIdx, const int idx)
+{
+ using namespace std;
+
+ checkSuperIndex("deletePack");
+ validSuperIndexAndIndex("deletePack", superIdx, idx);
+
+ int * vP = _values->getPointer();
+ int * siP(_super_index->getPointer()), *iP(_index->getPointer());
+ const int start = iP[siP[superIdx]+idx], end = iP[siP[superIdx]+idx+1];
+ // _values
+ copy(vP+end, vP+_values->getNbOfElems(), vP+start);
+ _values->reAlloc(_values->getNbOfElems() - (end-start));
+
+ // _index
+ int nt = _index->getNbOfElems();
+ copy(iP+siP[superIdx]+idx+1, iP+nt, iP+siP[superIdx]+idx);
+ _index->reAlloc(nt-1); iP = _index->getPointer(); // better not forget this ...
+ for(int ii = siP[superIdx]+idx; ii < nt-1; ii++)
+ iP[ii] -= (end-start);
+
+ // _super_index
+ for(int ii = superIdx+1; ii < _super_index->getNbOfElems(); ii++)
+ (siP[ii])--;
+}
+
+/**!
+ * Insert a new pack in super-pack at index 'superIdx'. The pack is inserted at the end of the pack list of the chosen super-pack.
+ */
+void MEDCouplingSkyLineArray::pushBackPack(const int superIdx, const int * packBg, const int * packEnd)
+{
+ using namespace std;
+
+ checkSuperIndex("pushBackPack");
+ validSuperIndex("pushBackPack", superIdx);
+
+ int *siP(_super_index->getPointer()), *iP(_index->getPointer());
+ const int sz(distance(packBg, packEnd));
+
+ // _values
+ _values->reAlloc(_values->getNbOfElems()+sz);
+ int * vPE(_values->getPointer()+_values->getNbOfElems());
+ int *vP(_values->getPointer());
+ copy(vP+iP[siP[superIdx+1]], vPE-sz, vP+iP[siP[superIdx+1]]+sz);
+ // insert pack
+ copy(packBg, packEnd, vP+iP[siP[superIdx+1]]);
+
+ // _index
+ int nt = _index->getNbOfElems();
+ _index->reAlloc(nt+1); iP = _index->getPointer();
+ copy(iP+siP[superIdx+1]+1, iP+nt, iP+siP[superIdx+1]+2);
+ iP[siP[superIdx+1]+1] = iP[siP[superIdx+1]] + sz;
+ for(int ii = siP[superIdx+1]+2; ii < nt+1; ii++)
+ iP[ii] += sz;
+
+ // _super_index
+ for(int ii = superIdx+1; ii < _super_index->getNbOfElems(); ii++)
+ (siP[ii])++;
+}
+
+/**
+ * Replace pack with absolute index 'idx' with the provided new pack. Function can be used either
+ * for 2-level SkyLine or 3-level SkyLine.
+ */
+void MEDCouplingSkyLineArray::replaceSimplePack(const int idx, const int * packBg, const int * packEnd)
+{
+ using namespace std;
+
+ validIndex("replaceSimplePack", idx);
+
+ int * iP(_index->getPointer());
+ int newSz = distance(packBg, packEnd);
+ const int start = iP[idx], end = iP[idx+1];
+
+ // _values
+ int initValSz = _values->getNbOfElems();
+ int deltaSz = newSz-(end-start); // can be negative
+ if (deltaSz)
+ {
+ if (deltaSz > 0)
+ _values->reAlloc(initValSz+deltaSz);
+ int *vP(_values->getPointer());
+ copy(vP+end, vP+initValSz, vP+end+deltaSz);
+ if (deltaSz < 0)
+ _values->reAlloc(initValSz+deltaSz);
+ }
+
+ // copy new pack
+ copy(packBg, packEnd, _values->getPointer()+start);
+
+ // _index
+ for(int ii = idx+1; ii < _index->getNbOfElems(); ii++)
+ iP[ii] += deltaSz;
+}
+
+/**
+ * Replace pack with super index 'superIdx' and index 'idx' with the provided new pack.
+ * Function can be used only for 3-level SkyLine.
+ */
+void MEDCouplingSkyLineArray::replacePack(const int superIdx, const int idx, const int * packBg, const int * packEnd)
+{
+ using namespace std;
+
+ checkSuperIndex("replacePack");
+ validSuperIndexAndIndex("replacePack", superIdx, idx);
+
+ int * siP(_super_index->getPointer()), *iP(_index->getPointer());
+ int newSz = distance(packBg, packEnd);
+ const int start = iP[siP[superIdx]+idx], end = iP[siP[superIdx]+idx+1];
+
+ // _values
+ int initValSz = _values->getNbOfElems();
+ int deltaSz = newSz-(end-start); // can be negative
+ if (deltaSz)
+ {
+ if (deltaSz > 0)
+ _values->reAlloc(initValSz+deltaSz);
+ int *vP(_values->getPointer());
+ copy(vP+end, vP+initValSz, vP+end+deltaSz);
+ if (deltaSz < 0)
+ _values->reAlloc(initValSz+deltaSz);
+ }
+
+ // copy new pack
+ copy(packBg, packEnd, _values->getPointer()+start);
+
+ // _index
+ for(int ii = siP[superIdx]+idx+1; ii < _index->getNbOfElems(); ii++)
+ iP[ii] += deltaSz;
+}