示例#1
0
 public object this[Slice slice] {
     get {
         int ostart, ostop, ostep;
         slice.indices(_length, out ostart, out ostop, out ostep);
         return(new Range(Compute(ostart), Compute(ostop), _step * ostep));
     }
 }
示例#2
0
 public object this[[NotNull] Slice slice] {
     get {
         int ostart, ostop, ostep;
         slice.indices(_length, out ostart, out ostop, out ostep);
         return(new PythonRange(Compute(ostart), Compute(ostop), (long)step * ostep));
     }
 }
示例#3
0
        public virtual object this[[NotNull] Slice slice] {
            get {
                int start, stop, step;
                slice.indices(_data.Length, out start, out stop, out step);

                if (start == 0 && stop == _data.Length && step == 1 &&
                    this.GetType() == typeof(PythonTuple))
                {
                    return(this);
                }
                return(MakeTuple(ArrayOps.GetSlice(_data, start, stop, step)));
            }
        }
示例#4
0
        /// <summary>
        /// MemoryView slicing is somewhat different and more restricted than
        /// standard slicing.
        /// </summary>
        private static void FixSlice(Slice slice, int len, out int start, out int stop)
        {
            if (slice.step != null)
            {
                throw PythonOps.NotImplementedError("");
            }

            slice.indices(len, out start, out stop, out _);

            if (stop < start)
            {
                // backwards iteration is interpreted as empty slice
                stop = start;
            }
        }
示例#5
0
        internal static Array GetSlice(Array data, int size, Slice slice)
        {
            if (data.Rank != 1)
            {
                throw Ops.NotImplementedError("slice on multi-dimensional array");
            }

            int start, stop, step;

            slice.indices(size, out start, out stop, out step);

            if ((step > 0 && start >= stop) || (step < 0 && start <= stop))
            {
                return(new object[0]);
            }

            if (step == 1)
            {
                int   n   = stop - start;
                Array ret = Array.CreateInstance(data.GetType().GetElementType(), n);
                Array.Copy(data, start + data.GetLowerBound(0), ret, 0, n);
                return(ret);
            }
            else
            {
                // could cause overflow (?)
                int      n   = step > 0 ? (stop - start + step - 1) / step : (stop - start + step + 1) / step;
                object[] ret = new object[n];
                int      ri  = 0;
                for (int i = 0, index = start; i < n; i++, index += step)
                {
                    ret[ri++] = data.GetValue(index + data.GetLowerBound(0));
                }
                return(ret);
            }
        }
示例#6
0
        public void DeleteItem(Slice /*!*/ slice)
        {
            if (slice == null)
            {
                throw PythonOps.TypeError("list indices must be integers or slices");
            }

            lock (this) {
                int start, stop, step;
                // slice is sealed, indices can't be user code...
                slice.indices(_bytes.Count, out start, out stop, out step);

                if (step > 0 && (start >= stop))
                {
                    return;
                }
                if (step < 0 && (start <= stop))
                {
                    return;
                }

                if (step == 1)
                {
                    int i = start;
                    for (int j = stop; j < _bytes.Count; j++, i++)
                    {
                        _bytes[i] = _bytes[j];
                    }
                    _bytes.RemoveRange(i, stop - start);
                    return;
                }
                else if (step == -1)
                {
                    int i = stop + 1;
                    for (int j = start + 1; j < _bytes.Count; j++, i++)
                    {
                        _bytes[i] = _bytes[j];
                    }
                    _bytes.RemoveRange(i, start - stop);
                    return;
                }
                else if (step < 0)
                {
                    // find "start" we will skip in the 1,2,3,... order
                    int i = start;
                    while (i > stop)
                    {
                        i += step;
                    }
                    i -= step;

                    // swap start/stop, make step positive
                    stop  = start + 1;
                    start = i;
                    step  = -step;
                }

                int curr, skip, move;
                // skip: the next position we should skip
                // curr: the next position we should fill in data
                // move: the next position we will check
                curr = skip = move = start;

                while (curr < stop && move < stop)
                {
                    if (move != skip)
                    {
                        _bytes[curr++] = _bytes[move];
                    }
                    else
                    {
                        skip += step;
                    }
                    move++;
                }
                while (stop < _bytes.Count)
                {
                    _bytes[curr++] = _bytes[stop++];
                }
                _bytes.RemoveRange(curr, _bytes.Count - curr);
            }
        }
示例#7
0
        public object this[Slice /*!*/ slice] {
            get {
                lock (this) {
                    List <byte> res = _bytes.Slice(slice);
                    if (res == null)
                    {
                        return(new ByteArray());
                    }

                    return(new ByteArray(res));
                }
            }
            set {
                if (slice == null)
                {
                    throw PythonOps.TypeError("bytearray indices must be integer or slice, not None");
                }

                // get a list of the bytes we're going to assign into the slice.  We accept:
                //      integers, longs, etc... - fill in an array of 0 bytes
                //      list of bytes, indexables, etc...

                IList <byte> list = value as IList <byte>;
                if (list == null)
                {
                    int?iVal = null;
                    if (value is int)
                    {
                        iVal = (int)value;
                    }
                    else if (value is Extensible <int> )
                    {
                        iVal = ((Extensible <int>)value).Value;
                    }
                    else if (value is BigInteger)
                    {
                        int intval;
                        if (((BigInteger)value).AsInt32(out intval))
                        {
                            iVal = intval;
                        }
                    }

                    if (iVal != null)
                    {
                        List <byte> newlist = new List <byte>();
                        newlist.Capacity = iVal.Value;
                        for (int i = 0; i < iVal; i++)
                        {
                            newlist.Add(0);
                        }
                        list = newlist;
                    }
                    else
                    {
                        IEnumerator ie = PythonOps.GetEnumerator(value);
                        list = new List <byte>();
                        while (ie.MoveNext())
                        {
                            list.Add(GetByte(ie.Current));
                        }
                    }
                }

                lock (this) {
                    if (slice.step != null)
                    {
                        // try to assign back to self: make a copy first
                        if (this == list)
                        {
                            value = CopyThis();
                        }
                        else if (list.Count == 0)
                        {
                            DeleteItem(slice);
                            return;
                        }

                        IList <byte> castedVal = GetBytes(value);

                        int start, stop, step;
                        slice.indices(_bytes.Count, out start, out stop, out step);

                        int n = (step > 0 ? (stop - start + step - 1) : (stop - start + step + 1)) / step;

                        // we don't use slice.Assign* helpers here because bytearray has different assignment semantics.

                        if (list.Count < n)
                        {
                            throw PythonOps.ValueError("too few items in the enumerator. need {0} have {1}", n, castedVal.Count);
                        }

                        for (int i = 0, index = start; i < castedVal.Count; i++, index += step)
                        {
                            if (i >= n)
                            {
                                if (index == _bytes.Count)
                                {
                                    _bytes.Add(castedVal[i]);
                                }
                                else
                                {
                                    _bytes.Insert(index, castedVal[i]);
                                }
                            }
                            else
                            {
                                _bytes[index] = castedVal[i];
                            }
                        }
                    }
                    else
                    {
                        int start, stop, step;
                        slice.indices(_bytes.Count, out start, out stop, out step);

                        SliceNoStep(start, stop, list);
                    }
                }
            }
        }
示例#8
0
            public object this[Slice index] {
                get {
                    if (index == null) throw PythonOps.TypeError("expected Slice, got None");

                    int start, stop, step;
                    index.indices(_data.Length, out start, out stop, out step);

                    PythonArray pa = new PythonArray(new string(_typeCode, 1), Type.Missing);
                    if (step < 0) {
                        for (int i = start; i > stop; i += step) {
                            pa._data.Append(_data.GetData(i));
                        }
                    } else {
                        for (int i = start; i < stop; i += step) {
                            pa._data.Append(_data.GetData(i));
                        }
                    }
                    return pa;
                }
                set {
                    if (index == null) throw PythonOps.TypeError("expected Slice, got None");

                    PythonArray pa = value as PythonArray;
                    if (pa != null && pa._typeCode != _typeCode) {
                        throw PythonOps.TypeError("bad array type");
                    }

                    if (index.step != null) {
                        if (Object.ReferenceEquals(value, this)) value = this.tolist();

                        index.DoSliceAssign(SliceAssign, _data.Length, value);
                    } else {
                        int start, stop, step;
                        index.indices(_data.Length, out start, out stop, out step);
                        if (stop < start) {
                            stop = start;
                        }

                        // replace between start & stop w/ values
                        IEnumerator ie = PythonOps.GetEnumerator(value);

                        ArrayData newData = CreateData(_typeCode);
                        for (int i = 0; i < start; i++) {
                            newData.Append(_data.GetData(i));
                        }

                        while (ie.MoveNext()) {
                            newData.Append(ie.Current);
                        }

                        for (int i = stop; i < _data.Length; i++) {
                            newData.Append(_data.GetData(i));
                        }

                        _data = newData;
                    }
                }
            }
示例#9
0
            public void __delitem__(Slice slice) {
                if (slice == null) throw PythonOps.TypeError("expected Slice, got None");

                int start, stop, step;
                // slice is sealed, indices can't be user code...
                slice.indices(_data.Length, out start, out stop, out step);

                if (step > 0 && (start >= stop)) return;
                if (step < 0 && (start <= stop)) return;

                if (step == 1) {
                    int i = start;
                    for (int j = stop; j < _data.Length; j++, i++) {
                        _data.SetData(i, _data.GetData(j));
                    }
                    for (i = 0; i < stop - start; i++) {
                        _data.RemoveAt(_data.Length - 1);
                    }
                    return;
                }
                if (step == -1) {
                    int i = stop + 1;
                    for (int j = start + 1; j < _data.Length; j++, i++) {
                        _data.SetData(i, _data.GetData(j));
                    }
                    for (i = 0; i < stop - start; i++) {
                        _data.RemoveAt(_data.Length - 1);
                    }
                    return;
                }

                if (step < 0) {
                    // find "start" we will skip in the 1,2,3,... order
                    int i = start;
                    while (i > stop) {
                        i += step;
                    }
                    i -= step;

                    // swap start/stop, make step positive
                    stop = start + 1;
                    start = i;
                    step = -step;
                }

                int curr, skip, move;
                // skip: the next position we should skip
                // curr: the next position we should fill in data
                // move: the next position we will check
                curr = skip = move = start;

                while (curr < stop && move < stop) {
                    if (move != skip) {
                        _data.SetData(curr++, _data.GetData(move));
                    } else
                        skip += step;
                    move++;
                }
                while (stop < _data.Length) {
                    _data.SetData(curr++, _data.GetData(stop++));
                }
                while (_data.Length > curr) {
                    _data.RemoveAt(_data.Length - 1);
                }
            }
示例#10
0
        public void DeleteItem(Slice slice)
        {
            lock (this) {
                int start, stop, step;
                // slice is sealed, indicies can't be user code...
                slice.indices(size, out start, out stop, out step);

                if (step > 0 && (start >= stop))
                {
                    return;
                }
                if (step < 0 && (start <= stop))
                {
                    return;
                }

                if (step == 1)
                {
                    int i = start;
                    for (int j = stop; j < size; j++, i++)
                    {
                        data[i] = data[j];
                    }
                    size -= stop - start;
                    return;
                }
                if (step == -1)
                {
                    int i = stop + 1;
                    for (int j = start + 1; j < size; j++, i++)
                    {
                        data[i] = data[j];
                    }
                    size -= start - stop;
                    return;
                }

                if (step < 0)
                {
                    // find "start" we will skip in the 1,2,3,... order
                    int i = start;
                    while (i > stop)
                    {
                        i += step;
                    }
                    i -= step;

                    // swap start/stop, make step positive
                    stop  = start + 1;
                    start = i;
                    step  = -step;
                }

                int curr, skip, move;
                // skip: the next position we should skip
                // curr: the next position we should fill in data
                // move: the next position we will check
                curr = skip = move = start;

                while (curr < stop && move < stop)
                {
                    if (move != skip)
                    {
                        data[curr++] = data[move];
                    }
                    else
                    {
                        skip += step;
                    }
                    move++;
                }
                while (stop < size)
                {
                    data[curr++] = data[stop++];
                }
                size = curr;
            }
        }
示例#11
0
        public object this[Slice slice] {
            get {
                if (slice == null)
                {
                    throw Ops.TypeError("list indicies must be integer or slice, not None");
                }

                int start, stop, step;
                slice.indices(size, out start, out stop, out step);

                if ((step > 0 && start >= stop) || (step < 0 && start <= stop))
                {
                    return(new List());
                }

                if (step == 1)
                {
                    int      n   = Math.Max(0, stop - start);
                    object[] ret = new object[n];
                    lock (this) Array.Copy(data, start, ret, 0, n);
                    return(new List(ret));
                }
                else
                {
                    // start/stop/step could be near Int32.MaxValue, and simply addition could cause overflow
                    int      n   = (int)(step > 0 ? (0L + stop - start + step - 1) / step : (0L + stop - start + step + 1) / step);
                    object[] ret = new object[n];
                    lock (this) {
                        int ri = 0;
                        for (int i = 0, index = start; i < n; i++, index += step)
                        {
                            ret[ri++] = data[index];
                        }
                    }
                    return(new List(ret));
                }
            }
            set {
                if (slice == null)
                {
                    throw Ops.TypeError("list indicies must be integer or slice, not None");
                }

                if (slice.step != null)
                {
                    // try to assign back to self: make a copy first
                    if (this == value)
                    {
                        value = new List(value);
                    }

                    slice.DoSliceAssign(this.SliceAssign, size, value);
                }
                else
                {
                    int start, stop, step;
                    slice.indices(size, out start, out stop, out step);
                    if (start > stop)
                    {
                        return;
                    }

                    SliceNoStep(start, stop, value);
                }
            }
        }
示例#12
0
        public static string __getitem__(string s, Slice slice)
        {
            if (slice == null) throw Ops.TypeError("string indicies must be slices or integers");
            int start, stop, step;
            slice.indices(s.Length, out start, out stop, out step);
            if (step == 1) {
                return stop > start ? s.Substring(start, stop - start) : String.Empty;
            } else {
                int index = 0;
                char[] newData;
                if (step > 0) {
                    if (start > stop) return String.Empty;

                    int icnt = (stop - start + step - 1) / step;
                    newData = new char[icnt];
                    for (int i = start; i < stop; i += step) {
                        newData[index++] = s[i];
                    }
                } else {
                    if (start < stop) return String.Empty;

                    int icnt = (stop - start + step + 1) / step;
                    newData = new char[icnt];
                    for (int i = start; i > stop; i += step) {
                        newData[index++] = s[i];
                    }
                }
                return new string(newData);
            }
        }
示例#13
0
        internal static Array GetSlice(Array data, int size, Slice slice)
        {
            if (data.Rank != 1) throw Ops.NotImplementedError("slice on multi-dimensional array");

            int start, stop, step;
            slice.indices(size, out start, out stop, out step);

            if ((step > 0 && start >= stop) || (step < 0 && start <= stop)) {
                if (data.GetType().GetElementType() == typeof(object))
                    return Ops.EMPTY;

                return Array.CreateInstance(data.GetType().GetElementType(), 0);
            }

            if (step == 1) {
                int n = stop - start;
                Array ret = Array.CreateInstance(data.GetType().GetElementType(), n);
                Array.Copy(data, start + data.GetLowerBound(0), ret, 0, n);
                return ret;
            } else {
                // could cause overflow (?)
                int n = step > 0 ? (stop - start + step - 1) / step : (stop - start + step + 1) / step;
                Array ret = Array.CreateInstance(data.GetType().GetElementType(), n);
                int ri = 0;
                for (int i = 0, index = start; i < n; i++, index += step) {
                    ret.SetValue(data.GetValue(index + data.GetLowerBound(0)), ri++);
                }
                return ret;
            }
        }
示例#14
0
文件: array.cs 项目: Hank923/ironruby
            public object this[Slice index] {
                get {
                    if (index == null) throw PythonOps.TypeError("expected Slice, got None");

                    int start, stop, step;
                    index.indices(_data.Length, out start, out stop, out step);

                    PythonArray pa = new PythonArray(new string(_typeCode, 1), Type.Missing);
                    if (step < 0) {
                        for (int i = start; i > stop; i += step) {
                            pa._data.Append(_data.GetData(i));
                        }
                    } else {
                        for (int i = start; i < stop; i += step) {
                            pa._data.Append(_data.GetData(i));
                        }
                    }
                    return pa;
                }
                set {
                    if (index == null) throw PythonOps.TypeError("expected Slice, got None");

                    CheckSliceAssignType(value);

                    if (index.step != null) {
                        if (Object.ReferenceEquals(value, this)) value = this.tolist();

                        index.DoSliceAssign(SliceAssign, _data.Length, value);
                    } else {
                        int start, stop, step;
                        index.indices(_data.Length, out start, out stop, out step);
                        if (stop < start) {
                            stop = start;
                        }

                        SliceNoStep(value, start, stop);
                    }
                }
            }