/// <summary> /// this helper function is used from all constructors /// </summary> /// <param name="data">storage of source array</param> /// <param name="indexOffset">ILIndexOffset mapping for reference arrays</param> /// <param name="dimensions">Dimension specification</param> /// <param name="startPos">enumeration value where to set the initial element position </param> /// <param name="leadingDimension">the dimension, the iterator is going to walk along</param> private void commonConstruct(BaseT[] data, ILIndexOffset indexOffset, ILDimension dimensions, ILIteratorPositions startPos, int leadingDimension) { m_data = data; m_leadDim = leadingDimension % dimensions.NumberOfDimensions; m_dataLenghtMinus1 = m_data.Length - 1; if (indexOffset == null) { m_increment = dimensions.SequentialIndexDistance(leadingDimension); switch (startPos) { case ILIteratorPositions.ILStart: m_pos = 0; break; case ILIteratorPositions.ILMiddle: m_pos = (int)(m_data.Length / 2); break; case ILIteratorPositions.ILEnd: m_pos = m_dataLenghtMinus1; break; } } else { int nrDims = indexOffset.Length; int curDim = (m_leadDim + 1) % nrDims; int curDimLen = dimensions[curDim]; m_indexOffset = indexOffset; m_leadDimIdx = indexOffset[curDim]; m_higherDimsIdx = new int[dimensions.NumberOfElements / dimensions[m_leadDim]]; int[] curPos = new int[dimensions.NumberOfDimensions]; // create int vector holding presummed higher dimension indices unsafe { fixed(int *tmpHighDims = m_higherDimsIdx, tmpLeadDim = m_leadDimIdx, pCurPos = curPos) { int *pHighDimsIdx = tmpHighDims; int *pHighDimsLast = pHighDimsIdx + m_higherDimsIdx.Length; int *pLeadDimIdx = tmpLeadDim; int *pCurPosDim = pCurPos; int curIdxSum = 0; int d; // sum all idxOffset[d,0] as start value for (d = 2; d < nrDims; d++) { curIdxSum += indexOffset[(m_leadDim + d) % nrDims, 0]; } do { // tmp leadDim is 1 dim larger than real leadDim // sum leadDim for (int i = 0; i < curDimLen; i++) { *pHighDimsIdx++ = curIdxSum + *pLeadDimIdx++; } // start increasing at 2 dims higher than lead dim pLeadDimIdx = tmpLeadDim; for (d = 2; pHighDimsIdx < pHighDimsLast && d < nrDims; d++) { curDim = (d + m_leadDim) % nrDims; pCurPosDim = pCurPos + curDim; curIdxSum -= m_indexOffset[curDim, *pCurPosDim]; *pCurPosDim = *pCurPosDim + 1; if (*pCurPosDim < dimensions[curDim]) { curIdxSum += m_indexOffset[curDim, *pCurPosDim]; break; } *pCurPosDim = 0; curIdxSum += m_indexOffset[curDim, *pCurPosDim]; } } while (pHighDimsIdx < pHighDimsLast && d < nrDims); } } m_leadDimIdx = indexOffset[m_leadDim]; // get start/ end positions switch (startPos) { case ILIteratorPositions.ILStart: m_curLeadIdx = 0; m_curHighDim = 0; m_pos = m_leadDimIdx[0] + m_higherDimsIdx[0]; break; case ILIteratorPositions.ILMiddle: m_curLeadIdx = 0; m_curHighDim = (int)(m_higherDimsIdx.Length / 2.0); m_pos = m_leadDimIdx[0] + m_higherDimsIdx[m_curHighDim]; break; case ILIteratorPositions.ILEnd: m_curLeadIdx = m_leadDimIdx.Length - 1; m_curHighDim = m_higherDimsIdx.Length - 1; m_pos = m_leadDimIdx[m_curLeadIdx] + m_higherDimsIdx[m_curHighDim]; break; } } // determine if this storage can be altered if (ILArray <BaseT> .GetNumberOfReferences(m_data) > 1) { m_readonly = true; } else { m_readonly = false; } }
// detaching a ranged,shifted storage to new physical storage public void Test_detach() { int errorCode = 0; // success? try { object[] data = new object[120]; for (int i = 120; i-- > 0; ) data[i] = (double)i; ILArray<object> B = new ILArray<object>(data, 5, 4, 1, 3, 2, 1 ); ILArray<object> A = B[3,"0:2,4;1,3;0;2,1,0,1"]; if (B.m_data.GetHashCode() != A.m_data.GetHashCode()) throw new Exception(); if (A.GetNumberOfReferences() != 2) throw new Exception(); A.Detach(); errorCode = 0; if (Object.Equals(A, null)) throw new Exception(); errorCode = 1; if (A.Dimensions.NumberOfDimensions != 3) throw new Exception(); errorCode = 2; if (A.Dimensions[0] != 4 | A.Dimensions[1] != 4 | A.Dimensions[2] != 2) throw new Exception(); errorCode = 3; object[] mdata = (object[])A.m_data; if (mdata.Length != 32 || A.Dimensions.NumberOfElements != 32) throw new Exception(); errorCode = 4; // soll werte: double[] results = new double[32]{45,25,5,25,46,26,6,26,47,27,7,27,49,29 ,9,29,55,35,15,35,56,36,16,36,57,37,17,37,59,39,19,39}; ILIterator<object> I = A.CreateIterator(ILIteratorPositions.ILStart, 0); int count = 0; do { if (((Double)I.Value).CompareTo(results[count++]) != 0) throw new Exception("Values did not match!"); I.Increment(); } while (!I.IsAtStart()); errorCode = 5; mdata = (object[])A.m_data; for (int i = 0; i < A.Dimensions.NumberOfElements; i++) if (mdata[i] != data[(int)results[i]]) throw new Exception(); errorCode = 6; if (A.GetNumberOfReferences() != 1) throw new Exception(); errorCode = 7; if (B.GetNumberOfReferences() != 1) throw new Exception(); errorCode = 8; if (A.m_data == B.m_data) throw new Exception(); Success("Test_detach successful."); } catch (Exception e) { Error("Test_detach failed at step: " + errorCode + " Msg: " + e.Message); } }