diff options
author | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-03-12 12:35:14 +0100 |
---|---|---|
committer | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-03-12 12:35:14 +0100 |
commit | f8775b64f67cc464e024cf79cd98eed30c659d25 (patch) | |
tree | e38670c0a68d8fcc8e4e9d819c0a2fb2c27659d9 /src | |
parent | 147f9395449db7fcb32957ae840017cff2740831 (diff) |
implemented magic __compare() method
Diffstat (limited to 'src')
-rw-r--r-- | src/base.cpp | 22 | ||||
-rw-r--r-- | src/classbase.cpp | 51 |
2 files changed, 72 insertions, 1 deletions
diff --git a/src/base.cpp b/src/base.cpp index a9faac3..a77b30f 100644 --- a/src/base.cpp +++ b/src/base.cpp @@ -256,6 +256,28 @@ bool Base::__toBool() } /** + * Compare the object with a different object of the same type + * + * This method should return 0 if both objects are equal, a negative value + * if the 'this' object is smaller, and a positive value if the 'this' + * object is bigger. + * + * The passed in object is an instance of base + * + * @param that Object to compare with + * @return int + */ +bool Base::__compare(const Base &that) const +{ + // throw an exception that will be caught in the ClassBase class, + // so that the default implementation of the function can be called + throw NotImplemented(); + + // unreachable code + return 1; +} + +/** * End namespace */ } diff --git a/src/classbase.cpp b/src/classbase.cpp index 460bae3..f7d8d94 100644 --- a/src/classbase.cpp +++ b/src/classbase.cpp @@ -285,6 +285,9 @@ zend_object_handlers *ClassBase::objectHandlers() // handler to cast to a different type handlers.cast_object = &ClassBase::cast; + // method to compare two objects + handlers.compare_objects = &ClassBase::compare; + // remember that object is now initialized initialized = true; @@ -293,6 +296,52 @@ zend_object_handlers *ClassBase::objectHandlers() } /** + * Function to compare two objects + * @param object1 + * @param object2 + * @return int + */ +int ClassBase::compare(zval *object1, zval *object2) +{ + // prevent exceptions + try + { + // retrieve the class entry linked to this object + auto *entry = zend_get_class_entry(object1); + + // other object must be of the same type + if (entry != zend_get_class_entry(object2)) throw NotImplemented(); + + // we need the C++ class meta-information object + ClassBase *meta = cpp_class(entry); + + // get the base objects + Base *base1 = cpp_object(object1); + Base *base2 = cpp_object(object2); + + // run the compare method + return meta->compare(base1, base2); + } + catch (const NotImplemented &exception) + { + // it was not implemented, do we have a default? + if (!std_object_handlers.compare_objects) return 1; + + // call default + return std_object_handlers.compare_objects(object1, object2); + } + catch (Exception &exception) + { + // a Php::Exception was thrown by the extension __compare function, + // pass this on to user space + exception.process(); + + // what shall we return here... + return 1; + } +} + +/** * Function to cast the object to a different type * @param object * @param retval @@ -343,7 +392,7 @@ int ClassBase::cast(zval *object, zval *retval, int type) catch (const NotImplemented &exception) { // is there a default? - if (std_object_handlers.cast_object) return FAILURE; + if (!std_object_handlers.cast_object) return FAILURE; // call default return std_object_handlers.cast_object(object, retval, type); |