summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-03-09 22:37:41 +0100
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-03-09 22:37:41 +0100
commit49d88d98a0656233f15923d31ea67a1ed229e514 (patch)
tree04bb753e4d5434c46bd90048e52d22260052334d /include
parentbdca5b0454534413f10d13211885c086fafff35a (diff)
work in progress on iterators
Diffstat (limited to 'include')
-rw-r--r--include/class.h14
-rw-r--r--include/classbase.h19
-rw-r--r--include/interface.h14
-rw-r--r--include/iterator.h140
-rw-r--r--include/traversable.h8
-rw-r--r--include/value.h1
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;
};
/**