Пример #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DynamicArray{T}"/> class. If a capcity is omitted the
        /// <see cref="DEFAULTCAPACITY"/> is used for the missing dimension capacity.
        /// </summary>
        /// <param name="rank"> The dynamic array rank. </param>
        /// <param name="capacities"> The capacities to be used for the underlying buffer. </param>
        public DynamicArray(int rank, params int[] capacities)
        {
            this.counts = IndexesHelper.Zero(rank);
            int[] usedCapacities = IndexesHelper.Zero(rank);
            for (int i = 0; i < rank; ++i)
            {
                usedCapacities[i] = (i < capacities.Length ? capacities[i] : DEFAULTCAPACITY);
            }

            // NOTE will throw an ArgumentException if rank<1
            this.buffer = Array.CreateInstance(typeof(T), usedCapacities);
        }
Пример #2
0
        /// <summary>
        /// Ensures the given indexes falls into the lengths and capacities of the underlying array. If not, the
        /// capacities and lengths are updated accordingly. A new underlyting array may be allocated in order to adapt
        /// capacities.
        /// </summary>
        /// <param name="indexes"> The indexes that must fall within the array. </param>
        private void UpdateCountsAndCapacities(int[] indexes)
        {
            int[] newCounts       = IndexesHelper.Zero(this.Rank);
            int[] newCapacities   = IndexesHelper.Zero(this.Rank);
            bool  newArrayNeeded  = false;
            bool  newCountsNeeded = false;

            for (int dimension = 0; dimension < this.Rank; ++dimension)
            {
                int requestedIndex  = indexes[dimension];
                int currentCapacity = this.GetCapacity(dimension);
                int currentCount    = this.GetCount(dimension);
                newCounts[dimension]     = currentCount;
                newCapacities[dimension] = currentCapacity;
                if (requestedIndex < currentCount)
                {
                    continue;
                }

                newCountsNeeded      = true;
                newCounts[dimension] = requestedIndex + 1;
                if (newCounts[dimension] <= currentCapacity)
                {
                    continue;
                }

                newCapacities[dimension] = Math.Max(2 * currentCapacity, newCounts[dimension]);
                newArrayNeeded           = true;
            }

            if (!newCountsNeeded)
            {
                return;
            }

            if (newArrayNeeded)
            {
                Array             newData = Array.CreateInstance(typeof(T), newCapacities);
                IndexesEnumerator ienum   = new IndexesEnumerator(IndexesHelper.UpperBound(this.buffer));
                foreach (int[] idx in ienum)
                {
                    newData.SetValue(this.buffer.GetValue(idx), idx);
                }

                this.buffer = newData;
            }

            // NOTE New lengths are set after allocation to avoid lengths corruption on failure.
            Array.Copy(newCounts, this.counts, this.counts.Length);
        }
 public static IndexesEnumerator Enumerate(Array arr, bool reverse)
 {
     return(new IndexesEnumerator(IndexesHelper.UpperBound(arr), IndexesHelper.Zero(arr.Rank), reverse));
 }
 public IndexesEnumerator(int[] upperBound) : this(upperBound, IndexesHelper.Zero(upperBound.Length), false)
 {
 }