Browse Source

- php: added support for native Iterator and IteratorAggregate interfaces

Franco Ponticelli 16 years ago
parent
commit
21964904af
6 changed files with 75 additions and 8 deletions
  1. 1 0
      doc/CHANGES.txt
  2. 10 1
      std/Hash.hx
  3. 9 1
      std/IntHash.hx
  4. 11 2
      std/List.hx
  5. 34 4
      std/php/Boot.hx
  6. 10 0
      std/php/IteratorAggregate.hx

+ 1 - 0
doc/CHANGES.txt

@@ -50,6 +50,7 @@ TODO :
 	php: List iterator is now class based (faster)
 	php: fixed behavior of class variables having assigned functions
 	php: fixed php.db.Manager (was uncorrectly removing superclass fields)
+	php: added support for native Iterator and IteratorAggregate interfaces
 
 2009-03-22: 2.03
 	optimized Type.enumEq : use index instead of tag comparison for neko/flash9/php

+ 10 - 1
std/Hash.hx

@@ -28,7 +28,7 @@
 	Other kind of keys are not possible on all platforms since they
 	can't always be implemented efficiently.
 **/
-class Hash<T> {
+class Hash<T> #if php implements php.IteratorAggregate<T> #end {
 
 	private var h : #if flash9 flash.utils.Dictionary #elseif php ArrayAccess<T> #else Dynamic #end;
 
@@ -251,4 +251,13 @@ class Hash<T> {
 		s.add("}");
 		return s.toString();
 	}
+	
+	/**
+		Implement IteratorAggregate for native php iteration
+	**/
+	#if php
+	function getIterator() {
+		return iterator();
+	}
+	#end
 }

+ 9 - 1
std/IntHash.hx

@@ -27,7 +27,7 @@
 	Hashtable over a set of elements, using [Int] as keys.
 	On Flash and Javascript, the underlying structure is an Object.
 **/
-class IntHash<T> {
+class IntHash<T> #if php implements php.IteratorAggregate<T> #end {
 
 	private var h : #if flash9 flash.utils.Dictionary #elseif php ArrayAccess<Int> #else Dynamic #end;
 
@@ -232,4 +232,12 @@ class IntHash<T> {
 		return s.toString();
 	}
 
+	/**
+		Implement IteratorAggregate for native php iteration
+	**/
+	#if php
+	function getIterator() {
+		return iterator();
+	}
+	#end
 }

+ 11 - 2
std/List.hx

@@ -28,7 +28,7 @@
 	that are chained together. It's optimized so that adding or removing an
 	element doesn't imply to copy the whole array content everytime.
 **/
-class List<T> {
+class List<T> #if php implements php.IteratorAggregate<T> #end {
 
 	#if php
 	private var h : ArrayAccess<Dynamic>;
@@ -189,7 +189,7 @@ class List<T> {
 	**/
 	public function iterator() : Iterator<T> {
 #if php
-		return untyped __call__("new _hx_list_iterator", h);
+		return untyped __call__("new _hx_list_iterator", this);
 #else
 		return cast {
 			h : h,
@@ -277,4 +277,13 @@ class List<T> {
 		}
 		return b;
 	}
+	
+	/**
+		Implement IteratorAggregate for native php iteration
+	**/
+	#if php
+	function getIterator() {
+		return iterator();
+	}
+	#end
 }

+ 34 - 4
std/php/Boot.hx

@@ -23,7 +23,7 @@ function _hx_anonymous($arr = array()) {
 	return $o;
 }
 
-class _hx_array implements ArrayAccess {
+class _hx_array implements ArrayAccess, IteratorAggregate {
 	var $»a;
 	var $length;
 	function __construct($a = array()) {
@@ -52,6 +52,10 @@ class _hx_array implements ArrayAccess {
 	function iterator() {
 		return new _hx_array_iterator($this->»a);
 	}
+	
+	function getIterator() {
+		return $this->iterator();
+	}
 
 	function join($sep) {
 		return implode($this->»a, $sep);
@@ -358,14 +362,18 @@ function _hx_len($o) {
 	return is_string($o) ? strlen($o) : $o->length;
 }
 
-class _hx_list_iterator {
+class _hx_list_iterator implements Iterator {
 	private $»h;
-	public function __construct($h) {
-		$this->»h = $h;
+	private $»list;
+	private $»counter;
+	public function __construct($list) {
+		$this->»list = $list;
+		$this->rewind();
 	}
 
 	public function next() {
 		if($this->»h == null) return null;
+		$this->»counter++;
 		$x = $this->»h[0];
 		$this->»h = $this->»h[1];
 		return $x;
@@ -374,6 +382,28 @@ class _hx_list_iterator {
 	public function hasNext() {
 		return $this->»h != null;
 	}
+
+	public function current() {
+		if (!$this->hasNext()) return null;
+		return $this->»h[0];
+	}
+
+	public function key() {
+		return $this->»counter;
+	}
+
+	public function valid() {
+		return $this->current() !== null;
+	}
+
+	public function rewind() {
+		$this->»counter = -1;
+		$this->»h = $this->»list->h;
+	}
+
+	public function size() {
+		return $this->»list->length;
+	}
 }
 
 function _hx_null() {

+ 10 - 0
std/php/IteratorAggregate.hx

@@ -0,0 +1,10 @@
+package php;
+
+extern interface IteratorAggregate<T> {
+	/** 
+		This method is not public to not induce haXe users to use it ;) 
+		Use iterator() instead.
+		The return type would be Aggregator that is unusable in haXe 
+	**/
+	private function getIterator() : Iterator<T>; // 
+}