eo: Make efl_cast() return NULL if invalid cast
authorJean-Philippe Andre <jp.andre@samsung.com>
Mon, 29 May 2017 02:28:13 +0000 (11:28 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Mon, 29 May 2017 04:29:03 +0000 (13:29 +0900)
This makes it work like C++ dynamic_cast<> operator, so that
the return value will be NULL if the object is not an instance
of the given class.

In case of efl_super() we don't do it as efl_super is used A LOT
inside EFL itself (all constructors & destructors, for a start)
and efl_isa is in fact a bit expensive. efl_cast isn't really used
and is intended to be something like dynamic_cast.

For @cedric :)

src/lib/eo/eo.c

index a2db103..d4c3b49 100644 (file)
@@ -357,12 +357,18 @@ _efl_super_cast(const Eo *eo_id, const Efl_Class *cur_klass, Eina_Bool super)
 
 #ifdef EO_DEBUG
    if (EINA_UNLIKELY(!_eo_is_a_obj(eo_id) && !_eo_is_a_class(eo_id))) goto err_obj;
-   if (EINA_UNLIKELY(!efl_isa(eo_id, cur_klass))) goto err_obj_hierarchy;
 #endif
 
    if (EINA_UNLIKELY(!_eo_is_a_obj(eo_id)))
      goto do_klass;
 
+#ifndef EO_DEBUG
+   if (!super && EINA_UNLIKELY(!efl_isa(eo_id, cur_klass)))
+#else
+   if (EINA_UNLIKELY(!efl_isa(eo_id, cur_klass)))
+#endif
+     goto err_obj_hierarchy;
+
    EO_OBJ_POINTER_RETURN_VAL(eo_id, obj, NULL);
    obj->cur_klass = super_klass;
    obj->super = super;
@@ -383,10 +389,10 @@ err:
 err_obj:
    _EO_POINTER_ERR(eo_id, "Object (%p) is an invalid ref, class=%p (%s).", eo_id, cur_klass, efl_class_name_get(cur_klass));
    return NULL;
+#endif
 err_obj_hierarchy:
    _EO_POINTER_ERR(eo_id, "Object (%p) class=%p (%s) is not an instance of class=%p (%s).", eo_id, efl_class_get(eo_id), efl_class_name_get(eo_id), cur_klass, efl_class_name_get(cur_klass));
    return NULL;
-#endif
 }
 
 EAPI Eo *