@@ -767,17 +767,44 @@ PyTypeObject PyRange_Type = {
767767typedef struct {
768768 PyObject_HEAD
769769 long start ;
770+ long stop ;
770771 long step ;
771- long len ;
772772} rangeiterobject ;
773773
774+ /* Return number of items in range (lo, hi, step). step != 0
775+ * required. The result always fits in an unsigned long.
776+ */
777+ static unsigned long
778+ get_len_of_range (long lo , long hi , long step )
779+ {
780+ /* -------------------------------------------------------------
781+ If step > 0 and lo >= hi, or step < 0 and lo <= hi, the range is empty.
782+ Else for step > 0, if n values are in the range, the last one is
783+ lo + (n-1)*step, which must be <= hi-1. Rearranging,
784+ n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
785+ the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so
786+ the RHS is non-negative and so truncation is the same as the
787+ floor. Letting M be the largest positive long, the worst case
788+ for the RHS numerator is hi=M, lo=-M-1, and then
789+ hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough
790+ precision to compute the RHS exactly. The analysis for step < 0
791+ is similar.
792+ ---------------------------------------------------------------*/
793+ assert (step != 0 );
794+ if (step > 0 && lo < hi )
795+ return 1UL + (hi - 1UL - lo ) / step ;
796+ else if (step < 0 && lo > hi )
797+ return 1UL + (lo - 1UL - hi ) / (0UL - step );
798+ else
799+ return 0UL ;
800+ }
801+
774802static PyObject *
775803rangeiter_next (rangeiterobject * r )
776804{
777- if (r -> len > 0 ) {
805+ if (r -> step > 0 ? r -> start < r -> stop : r -> start > r -> stop ) {
778806 long result = r -> start ;
779807 r -> start += r -> step ;
780- r -> len -- ;
781808 return PyLong_FromLong (result );
782809 }
783810 return NULL ;
@@ -786,7 +813,8 @@ rangeiter_next(rangeiterobject *r)
786813static PyObject *
787814rangeiter_len (rangeiterobject * r , PyObject * Py_UNUSED (ignored ))
788815{
789- return PyLong_FromLong (r -> len );
816+ unsigned long ulen = get_len_of_range (r -> start , r -> stop , r -> step );
817+ return PyLong_FromUnsignedLong (ulen );
790818}
791819
792820PyDoc_STRVAR (length_hint_doc ,
@@ -802,7 +830,7 @@ rangeiter_reduce(rangeiterobject *r, PyObject *Py_UNUSED(ignored))
802830 start = PyLong_FromLong (r -> start );
803831 if (start == NULL )
804832 goto err ;
805- stop = PyLong_FromLong (r -> start + r -> len * r -> step );
833+ stop = PyLong_FromLong (r -> stop );
806834 if (stop == NULL )
807835 goto err ;
808836 step = PyLong_FromLong (r -> step );
@@ -831,10 +859,12 @@ rangeiter_setstate(rangeiterobject *r, PyObject *state)
831859 /* silently clip the index value */
832860 if (index < 0 )
833861 index = 0 ;
834- else if (index > r -> len )
835- index = r -> len ; /* exhausted iterator */
862+ else {
863+ unsigned long ulen = get_len_of_range (r -> start , r -> stop , r -> step );
864+ if ((unsigned long )index > ulen )
865+ index = (long )ulen ; /* exhausted iterator */
866+ }
836867 r -> start += index * r -> step ;
837- r -> len -= index ;
838868 Py_RETURN_NONE ;
839869}
840870
@@ -884,34 +914,6 @@ PyTypeObject PyRangeIter_Type = {
884914 0 , /* tp_members */
885915};
886916
887- /* Return number of items in range (lo, hi, step). step != 0
888- * required. The result always fits in an unsigned long.
889- */
890- static unsigned long
891- get_len_of_range (long lo , long hi , long step )
892- {
893- /* -------------------------------------------------------------
894- If step > 0 and lo >= hi, or step < 0 and lo <= hi, the range is empty.
895- Else for step > 0, if n values are in the range, the last one is
896- lo + (n-1)*step, which must be <= hi-1. Rearranging,
897- n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
898- the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so
899- the RHS is non-negative and so truncation is the same as the
900- floor. Letting M be the largest positive long, the worst case
901- for the RHS numerator is hi=M, lo=-M-1, and then
902- hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough
903- precision to compute the RHS exactly. The analysis for step < 0
904- is similar.
905- ---------------------------------------------------------------*/
906- assert (step != 0 );
907- if (step > 0 && lo < hi )
908- return 1UL + (hi - 1UL - lo ) / step ;
909- else if (step < 0 && lo > hi )
910- return 1UL + (lo - 1UL - hi ) / (0UL - step );
911- else
912- return 0UL ;
913- }
914-
915917/* Initialize a rangeiter object. If the length of the rangeiter object
916918 is not representable as a C long, OverflowError is raised. */
917919
@@ -922,46 +924,38 @@ fast_range_iter(long start, long stop, long step, long len)
922924 if (it == NULL )
923925 return NULL ;
924926 it -> start = start ;
927+ it -> stop = stop ;
925928 it -> step = step ;
926- it -> len = len ;
927929 return (PyObject * )it ;
928930}
929931
930932typedef struct {
931933 PyObject_HEAD
932934 PyObject * start ;
935+ PyObject * stop ;
933936 PyObject * step ;
934- PyObject * len ;
935937} longrangeiterobject ;
936938
937939static PyObject *
938940longrangeiter_len (longrangeiterobject * r , PyObject * no_args )
939941{
940- Py_INCREF (r -> len );
941- return r -> len ;
942+ return compute_range_length (r -> start , r -> stop , r -> step );
942943}
943944
944945static PyObject *
945946longrangeiter_reduce (longrangeiterobject * r , PyObject * Py_UNUSED (ignored ))
946947{
947- PyObject * product , * stop = NULL ;
948948 PyObject * range ;
949949
950- /* create a range object for pickling. Must calculate the "stop" value */
951- product = PyNumber_Multiply (r -> len , r -> step );
952- if (product == NULL )
953- return NULL ;
954- stop = PyNumber_Add (r -> start , product );
955- Py_DECREF (product );
956- if (stop == NULL )
957- return NULL ;
950+ /* create a range object for pickling. */
958951 Py_INCREF (r -> start );
952+ Py_INCREF (r -> stop );
959953 Py_INCREF (r -> step );
960954 range = (PyObject * )make_range_object (& PyRange_Type ,
961- r -> start , stop , r -> step );
955+ r -> start , r -> stop , r -> step );
962956 if (range == NULL ) {
963957 Py_DECREF (r -> start );
964- Py_DECREF (stop );
958+ Py_DECREF (r -> stop );
965959 Py_DECREF (r -> step );
966960 return NULL ;
967961 }
@@ -978,23 +972,28 @@ longrangeiter_setstate(longrangeiterobject *r, PyObject *state)
978972 int cmp ;
979973
980974 /* clip the value */
981- cmp = PyObject_RichCompareBool (state , zero , Py_LT );
975+ cmp = PyObject_RichCompareBool (state , zero , Py_LE );
982976 if (cmp < 0 )
983977 return NULL ;
984978 if (cmp > 0 ) {
985- state = zero ;
979+ Py_RETURN_NONE ;
986980 }
987- else {
988- cmp = PyObject_RichCompareBool (r -> len , state , Py_LT );
989- if (cmp < 0 )
990- return NULL ;
991- if (cmp > 0 )
992- state = r -> len ;
981+ PyObject * length = compute_range_length (r -> start , r -> stop , r -> step );
982+ if (length == NULL ) {
983+ return NULL ;
993984 }
994- PyObject * new_len = PyNumber_Subtract (r -> len , state );
995- if (new_len == NULL )
985+ cmp = PyObject_RichCompareBool (length , state , Py_LE );
986+ if (cmp < 0 ) {
987+ Py_DECREF (length );
996988 return NULL ;
997- Py_SETREF (r -> len , new_len );
989+ }
990+ if (cmp > 0 ) {
991+ state = length ;
992+ }
993+ else {
994+ Py_INCREF (state );
995+ Py_DECREF (length );
996+ }
998997 PyObject * product = PyNumber_Multiply (state , r -> step );
999998 if (product == NULL )
1000999 return NULL ;
@@ -1020,29 +1019,24 @@ static void
10201019longrangeiter_dealloc (longrangeiterobject * r )
10211020{
10221021 Py_XDECREF (r -> start );
1022+ Py_XDECREF (r -> stop );
10231023 Py_XDECREF (r -> step );
1024- Py_XDECREF (r -> len );
10251024 PyObject_Free (r );
10261025}
10271026
10281027static PyObject *
10291028longrangeiter_next (longrangeiterobject * r )
10301029{
1031- if (PyObject_RichCompareBool (r -> len , _PyLong_GetZero (), Py_GT ) != 1 )
1030+ int s = _PyLong_Sign (r -> step );
1031+ if (PyObject_RichCompareBool (r -> start , r -> stop , s > 0 ? Py_LT : Py_GT ) != 1 )
10321032 return NULL ;
10331033
10341034 PyObject * new_start = PyNumber_Add (r -> start , r -> step );
10351035 if (new_start == NULL ) {
10361036 return NULL ;
10371037 }
1038- PyObject * new_len = PyNumber_Subtract (r -> len , _PyLong_GetOne ());
1039- if (new_len == NULL ) {
1040- Py_DECREF (new_start );
1041- return NULL ;
1042- }
10431038 PyObject * result = r -> start ;
10441039 r -> start = new_start ;
1045- Py_SETREF (r -> len , new_len );
10461040 return result ;
10471041}
10481042
@@ -1129,11 +1123,11 @@ range_iter(PyObject *seq)
11291123 return NULL ;
11301124
11311125 it -> start = r -> start ;
1126+ it -> stop = r -> stop ;
11321127 it -> step = r -> step ;
1133- it -> len = r -> length ;
11341128 Py_INCREF (it -> start );
1129+ Py_INCREF (it -> stop );
11351130 Py_INCREF (it -> step );
1136- Py_INCREF (it -> len );
11371131 return (PyObject * )it ;
11381132}
11391133
@@ -1142,7 +1136,7 @@ range_reverse(PyObject *seq, PyObject *Py_UNUSED(ignored))
11421136{
11431137 rangeobject * range = (rangeobject * ) seq ;
11441138 longrangeiterobject * it ;
1145- PyObject * sum , * diff , * product ;
1139+ PyObject * product ;
11461140 long lstart , lstop , lstep , new_start , new_stop ;
11471141 unsigned long ulen ;
11481142
@@ -1213,22 +1207,18 @@ range_reverse(PyObject *seq, PyObject *Py_UNUSED(ignored))
12131207 return NULL ;
12141208 it -> start = it -> step = NULL ;
12151209
1216- /* start + (len - 1) * step */
1217- it -> len = range -> length ;
1218- Py_INCREF (it -> len );
1219-
1220- diff = PyNumber_Subtract (it -> len , _PyLong_GetOne ());
1221- if (!diff )
1210+ /* new_stop = start - step */
1211+ it -> stop = PyNumber_Subtract (range -> start , range -> step );
1212+ if (!it -> stop )
12221213 goto create_failure ;
12231214
1224- product = PyNumber_Multiply ( diff , range -> step );
1225- Py_DECREF ( diff );
1215+ /* new_start = new_stop + len * step */
1216+ product = PyNumber_Multiply ( range -> length , range -> step );
12261217 if (!product )
12271218 goto create_failure ;
12281219
1229- sum = PyNumber_Add (range -> start , product );
1220+ it -> start = PyNumber_Add (it -> stop , product );
12301221 Py_DECREF (product );
1231- it -> start = sum ;
12321222 if (!it -> start )
12331223 goto create_failure ;
12341224
0 commit comments