xref: /PHP-7.4/ext/ffi/tests/list.phpt (revision 361d0b34)
1--TEST--
2FFI Double linked lists
3--SKIPIF--
4<?php require_once('skipif.inc'); ?>
5--INI--
6ffi.enable=1
7--FILE--
8<?php
9class DList {
10	private static $ffi = null;
11	private $root;
12
13	function __construct() {
14		if (is_null(self::$ffi)) {
15			self::$ffi =
16				FFI::cdef("
17					typedef struct _dlist dlist;
18					struct _dlist {
19						int data;
20						dlist *prev;
21						dlist *next;
22					};
23				");
24		}
25		$node = FFI::addr(self::$ffi->new("dlist", false));
26		$node->data = 0;
27		$node->next = $node;
28		$node->prev = $node;
29		$this->root = $node;
30	}
31
32	function __destruct() {
33		$root = $this->root;
34		$node = $root->next;
35		while ($node != $root) {
36			$prev = $node;
37			$node = $node->next;
38			FFI::free($prev);
39		}
40		FFI::free($root);
41	}
42
43	function add(int $data) {
44		$node = FFI::addr(self::$ffi->new("dlist", false));
45		$node->data = $data;
46		$node->next = $this->root;
47		$node->prev = $this->root->prev;
48		$this->root->prev->next = $node;
49		$this->root->prev = $node;
50	}
51
52	function del(int $data) {
53		$root = $this->root;
54		$node = $root->next;
55		while ($node != $root) {
56			if ($node->data == $data) {
57				$node->prev->next = $node->next;
58				$node->next->prev = $node->prev;
59				FFI::free($node);
60				break;
61			}
62			$node = $node->next;
63		}
64	}
65
66	function print() {
67		echo "[";
68		$first = true;
69		$root = $this->root;
70		$node = $root->next;
71		while ($node != $root) {
72			if (!$first) {
73				echo ", ";
74			} else {
75				$first = false;
76			}
77			echo $node->data;
78			$node = $node->next;
79		}
80		echo "]\n";
81	}
82}
83
84$dlist = new Dlist;
85$dlist->add(1);
86$dlist->add(3);
87$dlist->add(5);
88$dlist->print();
89$dlist->del(3);
90$dlist->print();
91echo "OK\n";
92--EXPECT--
93[1, 3, 5]
94[1, 5]
95OK
96