Exemple #1
0
// TODO make this conform to CPython's definition of sort
STATIC void mp_quicksort(mp_obj_t *head, mp_obj_t *tail, mp_obj_t key_fn, bool reversed) {
    int op = reversed ? RT_BINARY_OP_MORE : RT_BINARY_OP_LESS;
    while (head < tail) {
        mp_obj_t *h = head - 1;
        mp_obj_t *t = tail;
        mp_obj_t v = key_fn == NULL ? tail[0] : rt_call_function_1(key_fn, tail[0]); // get pivot using key_fn
        for (;;) {
            do ++h; while (rt_binary_op(op, key_fn == NULL ? h[0] : rt_call_function_1(key_fn, h[0]), v) == mp_const_true);
            do --t; while (h < t && rt_binary_op(op, v, key_fn == NULL ? t[0] : rt_call_function_1(key_fn, t[0])) == mp_const_true);
            if (h >= t) break;
            mp_obj_t x = h[0];
            h[0] = t[0];
            t[0] = x;
        }
        mp_obj_t x = h[0];
        h[0] = tail[0];
        tail[0] = x;
        mp_quicksort(head, t, key_fn, reversed);
        head = h + 1;
    }
}
Exemple #2
0
// Don't pass RT_COMPARE_OP_NOT_EQUAL here
static bool list_cmp_helper(int op, mp_obj_t self_in, mp_obj_t another_in) {
    assert(MP_OBJ_IS_TYPE(self_in, &list_type));
    if (!MP_OBJ_IS_TYPE(another_in, &list_type)) {
        return false;
    }
    mp_obj_list_t *self = self_in;
    mp_obj_list_t *another = another_in;
    if (op == RT_COMPARE_OP_EQUAL && self->len != another->len) {
        return false;
    }

    // Let's deal only with > & >=
    if (op == RT_COMPARE_OP_LESS || op == RT_COMPARE_OP_LESS_EQUAL) {
        mp_obj_t t = self;
        self = another;
        another = t;
        if (op == RT_COMPARE_OP_LESS) {
            op = RT_COMPARE_OP_MORE;
        } else {
            op = RT_COMPARE_OP_MORE_EQUAL;
        }
    }

    int len = self->len < another->len ? self->len : another->len;
    bool eq_status = true; // empty lists are equal
    bool rel_status;
    for (int i = 0; i < len; i++) {
        eq_status = mp_obj_equal(self->items[i], another->items[i]);
        if (op == RT_COMPARE_OP_EQUAL && !eq_status) {
            return false;
        }
        rel_status = (rt_binary_op(op, self->items[i], another->items[i]) == mp_const_true);
        if (!eq_status && !rel_status) {
            return false;
        }
    }

    // If we had tie in the last element...
    if (eq_status) {
        // ... and we have lists of different lengths...
        if (self->len != another->len) {
            if (self->len < another->len) {
                // ... then longer list length wins (we deal only with >)
                return false;
            }
        } else if (op == RT_COMPARE_OP_MORE) {
            // Otherwise, if we have strict relation, equality means failure
            return false;
        }
    }

    return true;
}
// Special-case comparison function for sequences of mp_obj_t
// Don't pass RT_BINARY_OP_NOT_EQUAL here
bool mp_seq_cmp_objs(int op, const mp_obj_t *items1, uint len1, const mp_obj_t *items2, uint len2) {
    if (op == RT_BINARY_OP_EQUAL && len1 != len2) {
        return false;
    }

    // Let's deal only with > & >=
    if (op == RT_BINARY_OP_LESS || op == RT_BINARY_OP_LESS_EQUAL) {
        SWAP(const mp_obj_t *, items1, items2);
        SWAP(uint, len1, len2);
        if (op == RT_BINARY_OP_LESS) {
            op = RT_BINARY_OP_MORE;
        } else {
            op = RT_BINARY_OP_MORE_EQUAL;
        }
    }

    int len = len1 < len2 ? len1 : len2;
    bool eq_status = true; // empty lists are equal
    bool rel_status;
    for (int i = 0; i < len; i++) {
        eq_status = mp_obj_equal(items1[i], items2[i]);
        if (op == RT_BINARY_OP_EQUAL && !eq_status) {
            return false;
        }
        rel_status = (rt_binary_op(op, items1[i], items2[i]) == mp_const_true);
        if (!eq_status && !rel_status) {
            return false;
        }
    }

    // If we had tie in the last element...
    if (eq_status) {
        // ... and we have lists of different lengths...
        if (len1 != len2) {
            if (len1 < len2) {
                // ... then longer list length wins (we deal only with >)
                return false;
            }
        } else if (op == RT_BINARY_OP_MORE) {
            // Otherwise, if we have strict relation, equality means failure
            return false;
        }
    }

    return true;
}