diff options
author | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-03-09 22:37:41 +0100 |
---|---|---|
committer | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-03-09 22:37:41 +0100 |
commit | 49d88d98a0656233f15923d31ea67a1ed229e514 (patch) | |
tree | 04bb753e4d5434c46bd90048e52d22260052334d /include | |
parent | bdca5b0454534413f10d13211885c086fafff35a (diff) |
work in progress on iterators
Diffstat (limited to 'include')
-rw-r--r-- | include/class.h | 14 | ||||
-rw-r--r-- | include/classbase.h | 19 | ||||
-rw-r--r-- | include/interface.h | 14 | ||||
-rw-r--r-- | include/iterator.h | 140 | ||||
-rw-r--r-- | include/traversable.h | 8 | ||||
-rw-r--r-- | include/value.h | 1 |
6 files changed, 188 insertions, 8 deletions
diff --git a/include/class.h b/include/class.h index e9a7179..6bcefda 100644 --- a/include/class.h +++ b/include/class.h @@ -154,7 +154,7 @@ private: * Construct a new instance of the object * @return Base */ - virtual Base* construct() override + virtual Base* construct() const override { // construct an instance return new T(); @@ -165,7 +165,7 @@ private: * @param orig * @return Base */ - virtual Base *clone(Base *orig) override + virtual Base *clone(Base *orig) const override { // cast to the original object T *t = (T *)orig; @@ -175,6 +175,16 @@ private: } /** + * Is this class traversable? + * @return bool + */ + virtual bool traversable() const override + { + // check if the templated class overrides from the base + return std::is_base_of<Traversable,T>::value; + } + + /** * Namespaces have access to the private base class */ friend class Namespace; diff --git a/include/classbase.h b/include/classbase.h index 81454ba..1be2538 100644 --- a/include/classbase.h +++ b/include/classbase.h @@ -97,14 +97,20 @@ public: * Construct a new instance of the object * @return Base */ - virtual Base* construct() = 0; + virtual Base* construct() const = 0; /** * Create a clone of an object * @param orig * @return Base */ - virtual Base *clone(Base *orig) = 0; + virtual Base *clone(Base *orig) const = 0; + + /** + * Is this a traversable class? + * @return bool + */ + virtual bool traversable() const = 0; /** * Initialize the class, given its name @@ -283,6 +289,15 @@ private: static struct _zend_object_handlers *objectHandlers(); /** + * Function to create a new iterator to iterate over an object + * @param entry The class entry + * @param object The object to iterate over + * @param by_ref ????? + * @return zend_object_iterator* Pointer to the iterator + */ + static struct _zend_object_iterator *getIterator(struct _zend_class_entry *entry, struct _zval_struct *object, int by_ref); + + /** * Name of the class * @var string */ diff --git a/include/interface.h b/include/interface.h index b3031e9..bdff75d 100644 --- a/include/interface.h +++ b/include/interface.h @@ -43,7 +43,7 @@ private: * Construct a new instance of the object * @return Base */ - virtual Base* construct() override + virtual Base* construct() const override { // this does not occur for interfaces return nullptr; @@ -54,11 +54,21 @@ private: * @param orig * @return Base */ - virtual Base* clone(Base *orig) override + virtual Base* clone(Base *orig) const override { // this does not occur for interfaces return nullptr; } + + /** + * Is this a traversable interface? + * @return bool + */ + virtual bool traversable() const override + { + // interfaces are never traversed + return false; + } /** * Namespaces have access to the private base class diff --git a/include/iterator.h b/include/iterator.h new file mode 100644 index 0000000..3c8f870 --- /dev/null +++ b/include/iterator.h @@ -0,0 +1,140 @@ +/** + * Iterator.h + * + * Base class for iterators. Extension writers that want to create traversable + * classes, should override this class and implement all pure virtual methods + * in it. + * + * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> + * @copyright 2014 Copernica BV + */ + +/** + * Forward declarations + */ +struct _zend_object_iterator_funcs; + +/** + * Set up namespace + */ +namespace Php { + +/** + * Class definition + */ +class Iterator +{ +public: + /** + * Constructor + * @param base Class over which the iterator is iterating + */ + Iterator(Base *base) : _object(base) {} + + /** + * Destructor + */ + virtual ~Iterator() {} + + /** + * Is the iterator on a valid position + * @return bool + */ + virtual bool valid() = 0; + + /** + * The value at the current position + * @return Value + */ + virtual Value current() = 0; + + /** + * The key at the current position + * @return Value + */ + virtual Value key() = 0; + + /** + * Move to the next position + */ + virtual void next() = 0; + + /** + * Rewind the iterator to the front position + */ + virtual void rewind() = 0; + +private: + /** + * During the lifetime of the iterator, the object over which + * it iterates is keps as a private variable. This ensures that + * this object is not destructed as long as the iterator exists + * @var Value + */ + Value _object; + + /** + * Internal method that returns the implementation object + * @return zend_object_iterator + */ + struct _zend_object_iterator *implementation(); + + /** + * Iterator destructor method + * @param iter + */ + static void destructor(struct _zend_object_iterator *iter); + + /** + * Iterator valid function + * Returns FAILURE or SUCCESS + * @param iter + * @return int + */ + static int valid(struct _zend_object_iterator *iter); + + /** + * Fetch the current item + * @param iter + * @param data + */ + static void current(struct _zend_object_iterator *iter, struct _zval_struct ***data); + + /** + * Fetch the key for the current element (optional, may be NULL). The key + * should be written into the provided zval* using the ZVAL_* macros. If + * this handler is not provided auto-incrementing integer keys will be + * used. + * @param iter + * @param data + */ + static void key(struct _zend_object_iterator *iter, struct _zval_struct *data); + + /** + * Step forwards to the next element + * @param iter + */ + static void next(struct _zend_object_iterator *iter); + + /** + * Rewind the iterator back to the start + * @param iter + */ + static void rewind(struct _zend_object_iterator *iter); + + /** + * Get access to all iterator functions + * @return zend_object_iterator_funcs + */ + static struct _zend_object_iterator_funcs *functions(); + + /** + * Classbase is a friend + */ + friend class ClassBase; +}; + +/** + * End namespace + */ +} diff --git a/include/traversable.h b/include/traversable.h index 57cc9bc..f81a5b4 100644 --- a/include/traversable.h +++ b/include/traversable.h @@ -19,8 +19,12 @@ namespace Php { */ class Traversable { - - +public: + /** + * Retrieve an instance of the iterator + * @return Iterator + */ + virtual Iterator *getIterator() = 0; }; /** diff --git a/include/value.h b/include/value.h index a1dd593..2ffbd7c 100644 --- a/include/value.h +++ b/include/value.h @@ -862,6 +862,7 @@ protected: friend class Globals; friend class Member; friend class ClassBase; + friend class Iterator; }; /** |