- 1318a1319,1507
- > static PyObject *
- > builtin_minmax(PyObject *self, PyObject *args, PyObject *kwds)
- > {
- > const char *name = "minmax";
- > PyObject *v, *it, *item, *val, *item2, *val2, *minitem, *minval, *maxitem, *maxval, *keyfunc=NULL;
- > PyObject *result = NULL;
- > int seqlen, cmp;
- >
- > if (PyTuple_Size(args) > 1)
- > v = args;
- > else if (!PyArg_UnpackTuple(args, (char *)name, 1, 1, &v))
- > return NULL;
- >
- > if (kwds != NULL && PyDict_Check(kwds) && PyDict_Size(kwds)) {
- > keyfunc = PyDict_GetItemString(kwds, "key");
- > if (PyDict_Size(kwds)!=1 || keyfunc == NULL) {
- > PyErr_Format(PyExc_TypeError,
- > "%s() got an unexpected keyword argument", name);
- > return NULL;
- > }
- > Py_INCREF(keyfunc);
- > }
- >
- > it = PyObject_GetIter(v);
- > if (it == NULL) {
- > Py_XDECREF(keyfunc);
- > return NULL;
- > }
- >
- > minitem = NULL; /* the results */
- > maxitem = NULL;
- > minval = NULL; /* the values associated with the results */
- > maxval = NULL;
- >
- > /* initialize min and max returns with the first item in the list */
- > item = PyIter_Next(it);
- > if (item == NULL)
- > {
- > //minitem = Py_None;
- > //Py_INCREF(minitem);
- > //maxitem = Py_None;
- > //Py_INCREF(maxitem);
- > goto EarlyExit_short_sequence;
- > }
- >
- > if (keyfunc != NULL) {
- > val = PyObject_CallFunctionObjArgs(keyfunc, item, NULL);
- > if (val == NULL)
- > goto Fail_it_item;
- > }
- > /* no key function; the value is the item */
- > else {
- > val = item;
- > // increment twice, as we will assign to both min and max return vals
- > Py_INCREF(val);
- > Py_INCREF(val);
- > }
- >
- > minitem = item;
- > minval = val;
- > maxitem = item; /* the result */
- > maxval = val; /* the value associated with the result */
- >
- > seqlen = PySequence_Length(v);
- >
- > // if even length sequence, put iter back at 0, to safely read by pairs
- > if (seqlen % 2 == 0) {
- > it = PyObject_GetIter(v);
- > }
- >
- > // read by pairs
- > while (( item = PyIter_Next(it) ) && (item2 = PyIter_Next(it))) {
- >
- > /* get the value from the key function */
- > if (keyfunc != NULL) {
- > val = PyObject_CallFunctionObjArgs(keyfunc, item, NULL);
- > val2 = PyObject_CallFunctionObjArgs(keyfunc, item2, NULL);
- > if (val == NULL || val2 == NULL)
- > goto Fail_it_item;
- > }
- > /* no key function; the value is the item */
- > else {
- > val = item;
- > Py_INCREF(val);
- > val2 = item2;
- > Py_INCREF(val2);
- > }
- >
- >
- > /*
- > if a > b:
- > a,b = b,a
- > */
- > cmp = PyObject_RichCompareBool(val, val2, Py_GT);
- > if (cmp < 0)
- > goto Fail_it_item_and_val;
- > else if (cmp > 0) {
- > PyObject* tmp;
- > tmp = val; val = val2; val2 = tmp;
- > tmp = item; item = item2; item2 = tmp;
- > }
- >
- > /*
- > if a < min_:
- > min_ = a
- > */
- > cmp = PyObject_RichCompareBool(val, minval, Py_LT);
- > if (cmp < 0)
- > goto Fail_it_item_and_val;
- > else if (cmp > 0) {
- > Py_DECREF(minval);
- > Py_DECREF(minitem);
- > minval = val;
- > minitem = item;
- > }
- > else {
- > Py_DECREF(item);
- > Py_DECREF(val);
- > }
- >
- > /*
- > if b > max_:
- > max_ = b
- > */
- > cmp = PyObject_RichCompareBool(val2, maxval, Py_GT);
- > if (cmp < 0)
- > goto Fail_it_item_and_val;
- > else if (cmp > 0) {
- > Py_DECREF(maxval);
- > Py_DECREF(maxitem);
- > maxval = val2;
- > maxitem = item2;
- > }
- > else {
- > Py_DECREF(item2);
- > Py_DECREF(val2);
- > }
- > }
- > if (PyErr_Occurred())
- > goto Fail_it;
- >
- > EarlyExit_short_sequence:
- > if (maxval == NULL) {
- > PyErr_Format(PyExc_ValueError,
- > "%s() arg is an empty sequence", name);
- > assert(maxitem == NULL);
- > }
- > else {
- > Py_DECREF(maxval);
- > Py_DECREF(minval);
- > }
- > Py_DECREF(it);
- > Py_XDECREF(keyfunc);
- >
- > if (maxitem != NULL) {
- > result = PyTuple_Pack(2, minitem, maxitem);
- > Py_DECREF(minitem);
- > Py_DECREF(maxitem);
- > }
- > else {
- > result = NULL;
- > }
- >
- > return result;
- >
- > Fail_it_item_and_val:
- > Py_DECREF(val);
- > Py_DECREF(val2);
- > Fail_it_item:
- > Py_DECREF(item);
- > Py_DECREF(item2);
- > Fail_it:
- > Py_XDECREF(minval);
- > Py_XDECREF(minitem);
- > Py_XDECREF(maxval);
- > Py_XDECREF(maxitem);
- > Py_DECREF(it);
- > Py_XDECREF(keyfunc);
- > return NULL;
- > }
- >
- > PyDoc_STRVAR(minmax_doc,
- > "minmax(iterable[, key=func]) -> value\n\
- > minmax(a, b, c, ...[, key=func]) -> value\n\
- > \n\
- > With a single iterable argument, return its smallest and largest items.\n\
- > With two or more arguments, return the smallest and largest arguments.");
- >
- >
- 2265a2455
- > {"minmax", (PyCFunction)builtin_minmax, METH_VARARGS | METH_KEYWORDS, minmax_doc},