
/* Tuple object implementation */

#include "Python.h"

/* Speed optimization to avoid frequent malloc/free of small tuples */
#ifndef PyTuple_MAXSAVESIZE
#define PyTuple_MAXSAVESIZE	20  /* Largest tuple to save on free list */
#endif
#ifndef PyTuple_MAXFREELIST 
#define PyTuple_MAXFREELIST  2000  /* Maximum number of tuples of each size to save */
#endif

#if PyTuple_MAXSAVESIZE > 0
/* Entries 1 up to PyTuple_MAXSAVESIZE are free lists, entry 0 is the empty
   tuple () of which at most one instance will be allocated.
*/
static PyTupleObject *free_list[PyTuple_MAXSAVESIZE];
static int numfree[PyTuple_MAXSAVESIZE];
#endif
#ifdef COUNT_ALLOCS
int fast_tuple_allocs;
int tuple_zero_allocs;
#endif

PyObject *
PyTuple_New(register Py_ssize_t size)
{
	register PyTupleObject *op;
	Py_ssize_t i;
	if (size < 0) {
		PyErr_BadInternalCall();
		return NULL;
	}
#if PyTuple_MAXSAVESIZE > 0
	if (size == 0 && free_list[0]) {
		op = free_list[0];
		Py_INCREF(op);
#ifdef COUNT_ALLOCS
		tuple_zero_allocs++;
#endif
		return (PyObject *) op;
	}
	if (size < PyTuple_MAXSAVESIZE && (op = free_list[size]) != NULL) {
		free_list[size] = (PyTupleObject *) op->ob_item[0];
		numfree[size]--;
#ifdef COUNT_ALLOCS
		fast_tuple_allocs++;
#endif
		/* Inline PyObject_InitVar */
#ifdef Py_TRACE_REFS
		Py_SIZE(op) = size;
		Py_TYPE(op) = &PyTuple_Type;
#endif
		_Py_NewReference((PyObject *)op);
	}
	else
#endif
	{
		Py_ssize_t nbytes = size * sizeof(PyObject *);
		/* Check for overflow */
		if (nbytes / sizeof(PyObject *) != (size_t)size ||
		    (nbytes > PY_SSIZE_T_MAX - sizeof(PyTupleObject) - sizeof(PyObject *)))
		{
			return PyErr_NoMemory();
		}
		nbytes += sizeof(PyTupleObject) - sizeof(PyObject *);

		op = PyObject_GC_NewVar(PyTupleObject, &PyTuple_Type, size);
		if (op == NULL)
			return NULL;
	}
	for (i=0; i < size; i++)
		op->ob_item[i] = NULL;
#if PyTuple_MAXSAVESIZE > 0
	if (size == 0) {
		free_list[0] = op;
		++numfree[0];
		Py_INCREF(op);	/* extra INCREF so that this is never freed */
	}
#endif
	_PyObject_GC_TRACK(op);
	return (PyObject *) op;
}

Py_ssize_t
PyTuple_Size(register PyObject *op)
{
	if (!PyTuple_Check(op)) {
		PyErr_BadInternalCall();
		return -1;
	}
	else
		return Py_SIZE(op);
}

PyObject *
PyTuple_GetItem(register PyObject *op, register Py_ssize_t i)
{
	if (!PyTuple_Check(op)) {
		PyErr_BadInternalCall();
		return NULL;
	}
	if (i < 0 || i >= Py_SIZE(op)) {
		PyErr_SetString(PyExc_IndexError, "tuple index out of range");
		return NULL;
	}
	return ((PyTupleObject *)op) -> ob_item[i];
}

int
PyTuple_SetItem(register PyObject *op, register Py_ssize_t i, PyObject *newitem)
{
	register PyObject *olditem;
	register PyObject **p;
	if (!PyTuple_Check(op) || op->ob_refcnt != 1) {
		Py_XDECREF(newitem);
		PyErr_BadInternalCall();
		return -1;
	}
	if (i < 0 || i >= Py_SIZE(op)) {
		Py_XDECREF(newitem);
		PyErr_SetString(PyExc_IndexError,
				"tuple assignment index out of range");
		return -1;
	}
	p = ((PyTupleObject *)op) -> ob_item + i;
	olditem = *p;
	*p = newitem;
	Py_XDECREF(olditem);
	return 0;
}

PyObject *
PyTuple_Pack(Py_ssize_t n, ...)
{
	Py_ssize_t i;
	PyObject *o;
	PyObject *result;
	PyObject **items;
	va_list vargs;

	va_start(vargs, n);
	result = PyTuple_New(n);
	if (result == NULL)
		return NULL;
	items = ((PyTupleObject *)result)->ob_item;
	for (i = 0; i < n; i++) {
		o = va_arg(vargs, PyObject *);
		Py_INCREF(o);
		items[i] = o;
	}
	va_end(vargs);
	return result;
}


/* Methods */

static void
tupledealloc(register PyTupleObject *op)
{
	register Py_ssize_t i;
	register Py_ssize_t len =  Py_SIZE(op);
	PyObject_GC_UnTrack(op);
	Py_TRASHCAN_SAFE_BEGIN(op)
	if (len > 0) {
		i = len;
		while (--i >= 0)
			Py_XDECREF(op->ob_item[i]);
#if PyTuple_MAXSAVESIZE > 0
		if (len < PyTuple_MAXSAVESIZE &&
		    numfree[len] < PyTuple_MAXFREELIST &&
		    Py_TYPE(op) == &PyTuple_Type)
		{
			op->ob_item[0] = (PyObject *) free_list[len];
			numfree[len]++;
			free_list[len] = op;
			goto done; /* return */
		}
#endif
	}
	Py_TYPE(op)->tp_free((PyObject *)op);
done:
	Py_TRASHCAN_SAFE_END(op)
}

static int
tupleprint(PyTupleObject *op, FILE *fp, int flags)
{
	Py_ssize_t i;
	Py_BEGIN_ALLOW_THREADS
	fprintf(fp, "(");
	Py_END_ALLOW_THREADS
	for (i = 0; i < Py_SIZE(op); i++) {
		if (i > 0) {
			Py_BEGIN_ALLOW_THREADS
			fprintf(fp, ", ");
			Py_END_ALLOW_THREADS
		}
		if (PyObject_Print(op->ob_item[i], fp, 0) != 0)
			return -1;
	}
	i = Py_SIZE(op);
	Py_BEGIN_ALLOW_THREADS
	if (i == 1)
		fprintf(fp, ",");
	fprintf(fp, ")");
	Py_END_ALLOW_THREADS
	return 0;
}

static PyObject *
tuplerepr(PyTupleObject *v)
{
	Py_ssize_t i, n;
	PyObject *s, *temp;
	PyObject *pieces, *result = NULL;

	n = Py_SIZE(v);
	if (n == 0)
		return PyString_FromString("()");

	/* While not mutable, it is still possible to end up with a cycle in a
	   tuple through an object that stores itself within a tuple (and thus
	   infinitely asks for the repr of itself). This should only be
	   possible within a type. */
	i = Py_ReprEnter((PyObject *)v);
	if (i != 0) {
		return i > 0 ? PyString_FromString("(...)") : NULL;
	}

	pieces = PyTuple_New(n);
	if (pieces == NULL)
		return NULL;

	/* Do repr() on each element. */
	for (i = 0; i < n; ++i) {
		if (Py_EnterRecursiveCall(" while getting the repr of a tuple"))
			goto Done;
		s = PyObject_Repr(v->ob_item[i]);
		Py_LeaveRecursiveCall();
		if (s == NULL)
			goto Done;
		PyTuple_SET_ITEM(pieces, i, s);
	}

	/* Add "()" decorations to the first and last items. */
	assert(n > 0);
	s = PyString_FromString("(");
	if (s == NULL)
		goto Done;
	temp = PyTuple_GET_ITEM(pieces, 0);
	PyString_ConcatAndDel(&s, temp);
	PyTuple_SET_ITEM(pieces, 0, s);
	if (s == NULL)
		goto Done;

	s = PyString_FromString(n == 1 ? ",)" : ")");
	if (s == NULL)
		goto Done;
	temp = PyTuple_GET_ITEM(pieces, n-1);
	PyString_ConcatAndDel(&temp, s);
	PyTuple_SET_ITEM(pieces, n-1, temp);
	if (temp == NULL)
		goto Done;

	/* Paste them all together with ", " between. */
	s = PyString_FromString(", ");
	if (s == NULL)
		goto Done;
	result = _PyString_Join(s, pieces);
	Py_DECREF(s);	

Done:
	Py_DECREF(pieces);
	Py_ReprLeave((PyObject *)v);
	return result;
}

/* The addend 82520, was selected from the range(0, 1000000) for 
   generating the greatest number of prime multipliers for tuples 
   upto length eight:

     1082527, 1165049, 1082531, 1165057, 1247581, 1330103, 1082533, 
     1330111, 1412633, 1165069, 1247599, 1495177, 1577699
*/

static long
tuplehash(PyTupleObject *v)
{
	register long x, y;
	register Py_ssize_t len = Py_SIZE(v);
	register PyObject **p;
	long mult = 1000003L;
	x = 0x345678L;
	p = v->ob_item;
	while (--len >= 0) {
		y = PyObject_Hash(*p++);
		if (y == -1)
			return -1;
		x = (x ^ y) * mult;
		/* the cast might truncate len; that doesn't change hash stability */
		mult += (long)(82520L + len + len);
	}
	x += 97531L;
	if (x == -1)
		x = -2;
	return x;
}

static Py_ssize_t
tuplelength(PyTupleObject *a)
{
	return Py_SIZE(a);
}

static int
tuplecontains(PyTupleObject *a, PyObject *el)
{
	Py_ssize_t i;
	int cmp;

	for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(a); ++i)
		cmp = PyObject_RichCompareBool(el, PyTuple_GET_ITEM(a, i),
						   Py_EQ);
	return cmp;
}

static PyObject *
tupleitem(register PyTupleObject *a, register Py_ssize_t i)
{
	if (i < 0 || i >= Py_SIZE(a)) {
		PyErr_SetString(PyExc_IndexError, "tuple index out of range");
		return NULL;
	}
	Py_INCREF(a->ob_item[i]);
	return a->ob_item[i];
}

static PyObject *
tupleslice(register PyTupleObject *a, register Py_ssize_t ilow, 
	   register Py_ssize_t ihigh)
{
	register PyTupleObject *np;
	PyObject **src, **dest;
	register Py_ssize_t i;
	Py_ssize_t len;
	if (ilow < 0)
		ilow = 0;
	if (ihigh > Py_SIZE(a))
		ihigh = Py_SIZE(a);
	if (ihigh < ilow)
		ihigh = ilow;
	if (ilow == 0 && ihigh == Py_SIZE(a) && PyTuple_CheckExact(a)) {
		Py_INCREF(a);
		return (PyObject *)a;
	}
	len = ihigh - ilow;
	np = (PyTupleObject *)PyTuple_New(len);
	if (np == NULL)
		return NULL;
	src = a->ob_item + ilow;
	dest = np->ob_item;
	for (i = 0; i < len; i++) {
		PyObject *v = src[i];
		Py_INCREF(v);
		dest[i] = v;
	}
	return (PyObject *)np;
}

PyObject *
PyTuple_GetSlice(PyObject *op, Py_ssize_t i, Py_ssize_t j)
{
	if (op == NULL || !PyTuple_Check(op)) {
		PyErr_BadInternalCall();
		return NULL;
	}
	return tupleslice((PyTupleObject *)op, i, j);
}

static PyObject *
tupleconcat(register PyTupleObject *a, register PyObject *bb)
{
	register Py_ssize_t size;
	register Py_ssize_t i;
	PyObject **src, **dest;
	PyTupleObject *np;
	if (!PyTuple_Check(bb)) {
		PyErr_Format(PyExc_TypeError,
       		     "can only concatenate tuple (not \"%.200s\") to tuple",
			     Py_TYPE(bb)->tp_name);
		return NULL;
	}
#define b ((PyTupleObject *)bb)
	size = Py_SIZE(a) + Py_SIZE(b);
	if (size < 0)
		return PyErr_NoMemory();
	np = (PyTupleObject *) PyTuple_New(size);
	if (np == NULL) {
		return NULL;
	}
	src = a->ob_item;
	dest = np->ob_item;
	for (i = 0; i < Py_SIZE(a); i++) {
		PyObject *v = src[i];
		Py_INCREF(v);
		dest[i] = v;
	}
	src = b->ob_item;
	dest = np->ob_item + Py_SIZE(a);
	for (i = 0; i < Py_SIZE(b); i++) {
		PyObject *v = src[i];
		Py_INCREF(v);
		dest[i] = v;
	}
	return (PyObject *)np;
#undef b
}

static PyObject *
tuplerepeat(PyTupleObject *a, Py_ssize_t n)
{
	Py_ssize_t i, j;
	Py_ssize_t size;
	PyTupleObject *np;
	PyObject **p, **items;
	if (n < 0)
		n = 0;
	if (Py_SIZE(a) == 0 || n == 1) {
		if (PyTuple_CheckExact(a)) {
			/* Since tuples are immutable, we can return a shared
			   copy in this case */
			Py_INCREF(a);
			return (PyObject *)a;
		}
		if (Py_SIZE(a) == 0)
			return PyTuple_New(0);
	}
	size = Py_SIZE(a) * n;
	if (size/Py_SIZE(a) != n)
		return PyErr_NoMemory();
	np = (PyTupleObject *) PyTuple_New(size);
	if (np == NULL)
		return NULL;
	p = np->ob_item;
	items = a->ob_item;
	for (i = 0; i < n; i++) {
		for (j = 0; j < Py_SIZE(a); j++) {
			*p = items[j];
			Py_INCREF(*p);
			p++;
		}
	}
	return (PyObject *) np;
}

static PyObject *
tupleindex(PyTupleObject *self, PyObject *args)
{
	Py_ssize_t i, start=0, stop=Py_SIZE(self);
	PyObject *v;

	if (!PyArg_ParseTuple(args, "O|O&O&:index", &v,
	                            _PyEval_SliceIndex, &start,
	                            _PyEval_SliceIndex, &stop))
		return NULL;
	if (start < 0) {
		start += Py_SIZE(self);
		if (start < 0)
			start = 0;
	}
	if (stop < 0) {
		stop += Py_SIZE(self);
		if (stop < 0)
			stop = 0;
	}
	for (i = start; i < stop && i < Py_SIZE(self); i++) {
		int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
		if (cmp > 0)
			return PyInt_FromSsize_t(i);
		else if (cmp < 0)
			return NULL;
	}
	PyErr_SetString(PyExc_ValueError, "tuple.index(x): x not in list");
	return NULL;
}

static PyObject *
tuplecount(PyTupleObject *self, PyObject *v)
{
	Py_ssize_t count = 0;
	Py_ssize_t i;

	for (i = 0; i < Py_SIZE(self); i++) {
		int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
		if (cmp > 0)
			count++;
		else if (cmp < 0)
			return NULL;
	}
	return PyInt_FromSsize_t(count);
}

static int
tupletraverse(PyTupleObject *o, visitproc visit, void *arg)
{
	Py_ssize_t i;

	for (i = Py_SIZE(o); --i >= 0; )
		Py_VISIT(o->ob_item[i]);
	return 0;
}

static PyObject *
tuplerichcompare(PyObject *v, PyObject *w, int op)
{
	PyTupleObject *vt, *wt;
	Py_ssize_t i;
	Py_ssize_t vlen, wlen;

	if (!PyTuple_Check(v) || !PyTuple_Check(w)) {
		Py_INCREF(Py_NotImplemented);
		return Py_NotImplemented;
	}

	vt = (PyTupleObject *)v;
	wt = (PyTupleObject *)w;

	vlen = Py_SIZE(vt);
	wlen = Py_SIZE(wt);

	/* Note:  the corresponding code for lists has an "early out" test
	 * here when op is EQ or NE and the lengths differ.  That pays there,
	 * but Tim was unable to find any real code where EQ/NE tuple
	 * compares don't have the same length, so testing for it here would
	 * have cost without benefit.
	 */

	/* Search for the first index where items are different.
	 * Note that because tuples are immutable, it's safe to reuse
	 * vlen and wlen across the comparison calls.
	 */
	for (i = 0; i < vlen && i < wlen; i++) {
		int k = PyObject_RichCompareBool(vt->ob_item[i],
						 wt->ob_item[i], Py_EQ);
		if (k < 0)
			return NULL;
		if (!k)
			break;
	}

	if (i >= vlen || i >= wlen) {
		/* No more items to compare -- compare sizes */
		int cmp;
		PyObject *res;
		switch (op) {
		case Py_LT: cmp = vlen <  wlen; break;
		case Py_LE: cmp = vlen <= wlen; break;
		case Py_EQ: cmp = vlen == wlen; break;
		case Py_NE: cmp = vlen != wlen; break;
		case Py_GT: cmp = vlen >  wlen; break;
		case Py_GE: cmp = vlen >= wlen; break;
		default: return NULL; /* cannot happen */
		}
		if (cmp)
			res = Py_True;
		else
			res = Py_False;
		Py_INCREF(res);
		return res;
	}

	/* We have an item that differs -- shortcuts for EQ/NE */
	if (op == Py_EQ) {
		Py_INCREF(Py_False);
		return Py_False;
	}
	if (op == Py_NE) {
		Py_INCREF(Py_True);
		return Py_True;
	}

	/* Compare the final item again using the proper operator */
	return PyObject_RichCompare(vt->ob_item[i], wt->ob_item[i], op);
}

static PyObject *
tuple_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);

static PyObject *
tuple_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
	PyObject *arg = NULL;
	static char *kwlist[] = {"sequence", 0};

	if (type != &PyTuple_Type)
		return tuple_subtype_new(type, args, kwds);
	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:tuple", kwlist, &arg))
		return NULL;

	if (arg == NULL)
		return PyTuple_New(0);
	else
		return PySequence_Tuple(arg);
}

static PyObject *
tuple_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
	PyObject *tmp, *newobj, *item;
	Py_ssize_t i, n;

	assert(PyType_IsSubtype(type, &PyTuple_Type));
	tmp = tuple_new(&PyTuple_Type, args, kwds);
	if (tmp == NULL)
		return NULL;
	assert(PyTuple_Check(tmp));
	newobj = type->tp_alloc(type, n = PyTuple_GET_SIZE(tmp));
	if (newobj == NULL)
		return NULL;
	for (i = 0; i < n; i++) {
		item = PyTuple_GET_ITEM(tmp, i);
		Py_INCREF(item);
		PyTuple_SET_ITEM(newobj, i, item);
	}
	Py_DECREF(tmp);
	return newobj;
}

PyDoc_STRVAR(tuple_doc,
"tuple() -> an empty tuple\n"
"tuple(sequence) -> tuple initialized from sequence's items\n"
"\n"
"If the argument is a tuple, the return value is the same object.");

static PySequenceMethods tuple_as_sequence = {
	(lenfunc)tuplelength,			/* sq_length */
	(binaryfunc)tupleconcat,		/* sq_concat */
	(ssizeargfunc)tuplerepeat,		/* sq_repeat */
	(ssizeargfunc)tupleitem,		/* sq_item */
	(ssizessizeargfunc)tupleslice,		/* sq_slice */
	0,					/* sq_ass_item */
	0,					/* sq_ass_slice */
	(objobjproc)tuplecontains,		/* sq_contains */
};

static PyObject*
tuplesubscript(PyTupleObject* self, PyObject* item)
{
	if (PyIndex_Check(item)) {
		Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
		if (i == -1 && PyErr_Occurred())
			return NULL;
		if (i < 0)
			i += PyTuple_GET_SIZE(self);
		return tupleitem(self, i);
	}
	else if (PySlice_Check(item)) {
		Py_ssize_t start, stop, step, slicelength, cur, i;
		PyObject* result;
		PyObject* it;
		PyObject **src, **dest;

		if (PySlice_GetIndicesEx((PySliceObject*)item,
				 PyTuple_GET_SIZE(self),
				 &start, &stop, &step, &slicelength) < 0) {
			return NULL;
		}

		if (slicelength <= 0) {
			return PyTuple_New(0);
		}
		else if (start == 0 && step == 1 &&
			 slicelength == PyTuple_GET_SIZE(self) &&
			 PyTuple_CheckExact(self)) {
			Py_INCREF(self);
			return (PyObject *)self;
		}
		else {
			result = PyTuple_New(slicelength);
			if (!result) return NULL;

			src = self->ob_item;
			dest = ((PyTupleObject *)result)->ob_item;
			for (cur = start, i = 0; i < slicelength; 
			     cur += step, i++) {
				it = src[cur];
				Py_INCREF(it);
				dest[i] = it;
			}
			
			return result;
		}
	}
	else {
		PyErr_Format(PyExc_TypeError, 
			     "tuple indices must be integers, not %.200s",
			     Py_TYPE(item)->tp_name);
		return NULL;
	}
}

static PyObject *
tuple_getnewargs(PyTupleObject *v)
{
	return Py_BuildValue("(N)", tupleslice(v, 0, Py_SIZE(v)));
	
}

static PyObject *
tuple_sizeof(PyTupleObject *self)
{
	Py_ssize_t res;

	res = PyTuple_Type.tp_basicsize + Py_SIZE(self) * sizeof(PyObject *);
	return PyInt_FromSsize_t(res);
}

PyDoc_STRVAR(index_doc,
"T.index(value, [start, [stop]]) -> integer -- return first index of value");
PyDoc_STRVAR(count_doc,
"T.count(value) -> integer -- return number of occurrences of value");
PyDoc_STRVAR(sizeof_doc,
"T.__sizeof__() -- size of T in memory, in bytes");

static PyMethodDef tuple_methods[] = {
	{"__getnewargs__",	(PyCFunction)tuple_getnewargs,	METH_NOARGS},
	{"__sizeof__",	(PyCFunction)tuple_sizeof, METH_NOARGS, sizeof_doc},
	{"index",	(PyCFunction)tupleindex,  METH_VARARGS, index_doc},
	{"count",	(PyCFunction)tuplecount,  METH_O, count_doc},
	{NULL,		NULL}		/* sentinel */
};

static PyMappingMethods tuple_as_mapping = {
	(lenfunc)tuplelength,
	(binaryfunc)tuplesubscript,
	0
};

static PyObject *tuple_iter(PyObject *seq);

PyTypeObject PyTuple_Type = {
	PyVarObject_HEAD_INIT(&PyType_Type, 0)
	"tuple",
	sizeof(PyTupleObject) - sizeof(PyObject *),
	sizeof(PyObject *),
	(destructor)tupledealloc,		/* tp_dealloc */
	(printfunc)tupleprint,			/* tp_print */
	0,					/* tp_getattr */
	0,					/* tp_setattr */
	0,					/* tp_compare */
	(reprfunc)tuplerepr,			/* tp_repr */
	0,					/* tp_as_number */
	&tuple_as_sequence,			/* tp_as_sequence */
	&tuple_as_mapping,			/* tp_as_mapping */
	(hashfunc)tuplehash,			/* tp_hash */
	0,					/* tp_call */
	0,					/* tp_str */
	PyObject_GenericGetAttr,		/* tp_getattro */
	0,					/* tp_setattro */
	0,					/* tp_as_buffer */
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
		Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TUPLE_SUBCLASS, /* tp_flags */
	tuple_doc,				/* tp_doc */
 	(traverseproc)tupletraverse,		/* tp_traverse */
	0,					/* tp_clear */
	tuplerichcompare,			/* tp_richcompare */
	0,					/* tp_weaklistoffset */
	tuple_iter,	    			/* tp_iter */
	0,					/* tp_iternext */
	tuple_methods,				/* tp_methods */
	0,					/* tp_members */
	0,					/* tp_getset */
	0,					/* tp_base */
	0,					/* tp_dict */
	0,					/* tp_descr_get */
	0,					/* tp_descr_set */
	0,					/* tp_dictoffset */
	0,					/* tp_init */
	0,					/* tp_alloc */
	tuple_new,				/* tp_new */
	PyObject_GC_Del,        		/* tp_free */
};

/* The following function breaks the notion that tuples are immutable:
   it changes the size of a tuple.  We get away with this only if there
   is only one module referencing the object.  You can also think of it
   as creating a new tuple object and destroying the old one, only more
   efficiently.  In any case, don't use this if the tuple may already be
   known to some other part of the code. */

int
_PyTuple_Resize(PyObject **pv, Py_ssize_t newsize)
{
	register PyTupleObject *v;
	register PyTupleObject *sv;
	Py_ssize_t i;
	Py_ssize_t oldsize;

	v = (PyTupleObject *) *pv;
	if (v == NULL || Py_TYPE(v) != &PyTuple_Type ||
	    (Py_SIZE(v) != 0 && Py_REFCNT(v) != 1)) {
		*pv = 0;
		Py_XDECREF(v);
		PyErr_BadInternalCall();
		return -1;
	}
	oldsize = Py_SIZE(v);
	if (oldsize == newsize)
		return 0;

	if (oldsize == 0) {
		/* Empty tuples are often shared, so we should never 
		   resize them in-place even if we do own the only
		   (current) reference */
		Py_DECREF(v);
		*pv = PyTuple_New(newsize);
		return *pv == NULL ? -1 : 0;
	}

	/* XXX UNREF/NEWREF interface should be more symmetrical */
	_Py_DEC_REFTOTAL;
	_PyObject_GC_UNTRACK(v);
	_Py_ForgetReference((PyObject *) v);
	/* DECREF items deleted by shrinkage */
	for (i = newsize; i < oldsize; i++) {
		Py_XDECREF(v->ob_item[i]);
		v->ob_item[i] = NULL;
	}
	sv = PyObject_GC_Resize(PyTupleObject, v, newsize);
	if (sv == NULL) {
		*pv = NULL;
		PyObject_GC_Del(v);
		return -1;
	}
	_Py_NewReference((PyObject *) sv);
	/* Zero out items added by growing */
	if (newsize > oldsize)
		memset(&sv->ob_item[oldsize], 0,
		       sizeof(*sv->ob_item) * (newsize - oldsize));
	*pv = (PyObject *) sv;
	_PyObject_GC_TRACK(sv);
	return 0;
}

int
PyTuple_ClearFreeList(void)
{
	int freelist_size = 0;
#if PyTuple_MAXSAVESIZE > 0
	int i;
	for (i = 1; i < PyTuple_MAXSAVESIZE; i++) {
		PyTupleObject *p, *q;
		p = free_list[i];
		freelist_size += numfree[i];
		free_list[i] = NULL;
		numfree[i] = 0;
		while (p) {
			q = p;
			p = (PyTupleObject *)(p->ob_item[0]);
			PyObject_GC_Del(q);
		}
	}
#endif
	return freelist_size;
}
	
void
PyTuple_Fini(void)
{
#if PyTuple_MAXSAVESIZE > 0
	/* empty tuples are used all over the place and applications may
	 * rely on the fact that an empty tuple is a singleton. */
	Py_XDECREF(free_list[0]);
	free_list[0] = NULL;

	(void)PyTuple_ClearFreeList();
#endif
}

/*********************** Tuple Iterator **************************/

typedef struct {
	PyObject_HEAD
	long it_index;
	PyTupleObject *it_seq; /* Set to NULL when iterator is exhausted */
} tupleiterobject;

static void
tupleiter_dealloc(tupleiterobject *it)
{
	_PyObject_GC_UNTRACK(it);
	Py_XDECREF(it->it_seq);
	PyObject_GC_Del(it);
}

static int
tupleiter_traverse(tupleiterobject *it, visitproc visit, void *arg)
{
	Py_VISIT(it->it_seq);
	return 0;
}

static PyObject *
tupleiter_next(tupleiterobject *it)
{
	PyTupleObject *seq;
	PyObject *item;

	assert(it != NULL);
	seq = it->it_seq;
	if (seq == NULL)
		return NULL;
	assert(PyTuple_Check(seq));

	if (it->it_index < PyTuple_GET_SIZE(seq)) {
		item = PyTuple_GET_ITEM(seq, it->it_index);
		++it->it_index;
		Py_INCREF(item);
		return item;
	}

	Py_DECREF(seq);
	it->it_seq = NULL;
	return NULL;
}

static PyObject *
tupleiter_len(tupleiterobject *it)
{
	Py_ssize_t len = 0;
	if (it->it_seq)
		len = PyTuple_GET_SIZE(it->it_seq) - it->it_index;
	return PyInt_FromSsize_t(len);
}

PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");

static PyMethodDef tupleiter_methods[] = {
	{"__length_hint__", (PyCFunction)tupleiter_len, METH_NOARGS, length_hint_doc},
 	{NULL,		NULL}		/* sentinel */
};

PyTypeObject PyTupleIter_Type = {
	PyVarObject_HEAD_INIT(&PyType_Type, 0)
	"tupleiterator",			/* tp_name */
	sizeof(tupleiterobject),		/* tp_basicsize */
	0,					/* tp_itemsize */
	/* methods */
	(destructor)tupleiter_dealloc,		/* tp_dealloc */
	0,					/* tp_print */
	0,					/* tp_getattr */
	0,					/* tp_setattr */
	0,					/* tp_compare */
	0,					/* tp_repr */
	0,					/* tp_as_number */
	0,					/* tp_as_sequence */
	0,					/* tp_as_mapping */
	0,					/* tp_hash */
	0,					/* tp_call */
	0,					/* tp_str */
	PyObject_GenericGetAttr,		/* tp_getattro */
	0,					/* tp_setattro */
	0,					/* tp_as_buffer */
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
	0,					/* tp_doc */
	(traverseproc)tupleiter_traverse,	/* tp_traverse */
	0,					/* tp_clear */
	0,					/* tp_richcompare */
	0,					/* tp_weaklistoffset */
	PyObject_SelfIter,			/* tp_iter */
	(iternextfunc)tupleiter_next,		/* tp_iternext */
	tupleiter_methods,			/* tp_methods */
	0,
};

static PyObject *
tuple_iter(PyObject *seq)
{
	tupleiterobject *it;

	if (!PyTuple_Check(seq)) {
		PyErr_BadInternalCall();
		return NULL;
	}
	it = PyObject_GC_New(tupleiterobject, &PyTupleIter_Type);
	if (it == NULL)
		return NULL;
	it->it_index = 0;
	Py_INCREF(seq);
	it->it_seq = (PyTupleObject *)seq;
	_PyObject_GC_TRACK(it);
	return (PyObject *)it;
}
