namespace Php {
    /**
     * PHP loose equality: `$left == $right`.
     */
    public bool eq (Php.zval left, Php.zval right) {
        if (left.get_value_type () == Php.ValueType.STRING || right.get_value_type () == Php.ValueType.STRING) {
            return zval_to_string (left) == zval_to_string (right);
        }
        return zval_to_double (left) == zval_to_double (right);
    }

    /**
     * PHP loose inequality: `$left != $right` or `$left <> $right`.
     */
    public bool ne (Php.zval left, Php.zval right) {
        return !eq (left, right);
    }

    /**
     * PHP strict equality: `$left === $right`.
     */
    public bool strict_eq (Php.zval left, Php.zval right) {
        if (left.get_value_type () != right.get_value_type ()) {
            return false;
        }
        switch (left.get_value_type ()) {
        case Php.ValueType.NULL:
            return true;
        case Php.ValueType.BOOL:
            return left.as_bool () == right.as_bool ();
        case Php.ValueType.INT:
            return left.as_int () == right.as_int ();
        case Php.ValueType.DOUBLE:
            return left.as_double () == right.as_double ();
        case Php.ValueType.STRING:
            return left.as_string () == right.as_string ();
        case Php.ValueType.ARRAY:
        case Php.ValueType.OBJECT:
            return left == right;
        default:
            return false;
        }
    }

    /**
     * PHP strict inequality: `$left !== $right`.
     */
    public bool strict_ne (Php.zval left, Php.zval right) {
        return !strict_eq (left, right);
    }
}
