
(provide (quote dll))

(defun dll-get-dummy-node (dll) (byte-code "‡" [dll] 1))

(defun dll-list-nodes (dll) (byte-code "A‡" [dll] 1))

(defun dll-set-from-node-list (dll list) (byte-code "Â	\"‡" [dll list setcdr] 3))

(defun dll-get-node-before (dll node) (byte-code "…	 A	=?… A‰ˆ‚  ˆ?… ÂÃ!ˆ‡" [dll node error "Node not on list"] 3))

(defmacro dll-insert-after (node element) (byte-code "ÄÅ!ÄÆ!Ç
D	DDÈÉ	ÊDEEE*‡" [node-v element-v node element make-symbol "node" "element" let setcdr cons cdr] 10))

(defmacro dll-element (dll node) "Get the element of a NODE in a doubly linked list DLL.
Args: DLL NODE." (byte-code "ÁD‡" [node car] 2))

(defun dll-create nil "\
Create an empty doubly linked list." (byte-code "ÁÀB‡" [nil DL-LIST] 2))

(defun dll-p (object) "\
Return t if OBJECT is a doubly linked list, otherwise return nil." (byte-code "Á!Â=‡" [object car-safe DL-LIST] 3))

(defun dll-enter-first (dll element) "\
Add an element first on a doubly linked list.
Args: DLL ELEMENT." (byte-code "Â	AB\"‡" [dll element setcdr] 4))

(defun dll-enter-last (dll element) "\
Add an element last on a doubly linked list.
Args: DLL ELEMENT." (byte-code "Å	Â\"ÆAB\"*‡" [node dll nil element element dll-get-node-before setcdr] 5))

(defun dll-enter-after (dll node element) "\
In the doubly linked list DLL, insert a node containing ELEMENT after NODE.
Args: DLL NODE ELEMENT." (byte-code "Å	\"ˆ	Æ

AB\"*‡" [dll node node element element dll-get-node-before setcdr] 5))

(defun dll-enter-before (dll node element) "\
In the doubly linked list DLL, insert a node containing ELEMENT before NODE.
Args: DLL NODE ELEMENT." (byte-code "Å	
\"ÆAB\"*‡" [node dll node element element dll-get-node-before setcdr] 5))

(defun dll-next (dll node) "\
Return the node after NODE, or nil if NODE is the last node.
Args: DLL NODE." (byte-code "Â	\"ˆ	A‡" [dll node dll-get-node-before] 3))

(defun dll-previous (dll node) "\
Return the node before NODE, or nil if NODE is the first node.
Args: DLL NODE." (byte-code "Ä	
\"	=ƒ Ã‚ )‡" [prev dll node nil dll-get-node-before] 3))

(defun dll-delete (dll node) "\
Delete NODE from the doubly linked list DLL.
Args: DLL NODE. Return the element of node." (byte-code "ÂÃ	\"	A\"ˆ	@‡" [dll node setcdr dll-get-node-before] 4))

(defun dll-delete-first (dll) "\
Delete the first NODE from the doubly linked list DLL.
Return the element. Args: DLL. Returns nil if the DLL was empty." (byte-code "A@ÁAA\"ˆ‡" [dll setcdr] 4))

(defun dll-delete-last (dll) "\
Delete the last NODE from the doubly linked list DLL.
Return the element. Args: DLL. Returns nil if the DLL was empty." (byte-code "Ä	Â\"Ä	\"	=ƒ Â‚ ÅÂ\"ˆ@*‡" [last dll nil semilast dll-get-node-before setcdr] 5))

(defun dll-first (dll) "\
Return the first element on the doubly linked list DLL.
Return nil if the list is empty. The element is not removed." (byte-code "A@‡" [dll] 1))

(defun dll-last (dll) "\
Return the last element on the doubly linked list DLL.
Return nil if the list is empty. The element is not removed." (byte-code "Ã	Â\"	=ƒ Â‚ @)‡" [last dll nil dll-get-node-before] 3))

(defun dll-nth (dll n) "\
Return the Nth node from the doubly linked list DLL.
 Args: DLL N
N counts from zero. If DLL is not that long, nil is returned.
If N is negative, return the -(N+1)th last element.
Thus, (dll-nth dll 0) returns the first node,
and (dll-nth dll -1) returns the last node." (byte-code "ÂYƒ Ã	A\"‚ ÄŽÅ	Æ	A!\"ˆÃ[	\")‡" [n dll 0 nthcdr ((byte-code "ÁÂA!\"‡" [dll setcdr nreverse] 4)) setcdr nreverse] 6))

(defun dll-empty (dll) "\
Return t if the doubly linked list DLL is empty, nil otherwise" (byte-code "A?‡" [dll] 1))

(defun dll-length (dll) "\
Returns the number of elements in the doubly linked list DLL." (byte-code "AG‡" [dll] 1))

(defun dll-copy (dll &optional element-copy-fnc) "\
Return a copy of the doubly linked list DLL.
If optional second argument ELEMENT-COPY-FNC is non-nil it should be
a function that takes one argument, an element, and returns a copy of it.
If ELEMENT-COPY-FNC is not given the elements are not copied." (byte-code "ƒ ÂÃ	A\"B‚ Ä	!‡" [element-copy-fnc dll DL-LIST mapcar copy-sequence] 4))

(defun dll-all (dll) "\
Return all elements on the double linked list DLL as an ordinary list." (byte-code "A‡" [dll] 1))

(defun dll-clear (dll) "\
Clear the doubly linked list DLL, i.e. make it completely empty." (byte-code "ÂÁ\"‡" [dll nil setcdr] 3))

(defun dll-map (map-function dll) "\
Apply MAP-FUNCTION to all elements in the doubly linked list DLL.
The function is applied to the first element first." (byte-code "Â	A\"‡" [map-function dll mapcar] 3))

(defun dll-map-reverse (map-function dll) "\
Apply MAP-FUNCTION to all elements in the doubly linked list DLL.
The function is applied to the last element first." (byte-code "ÂŽÃÄA!\")‡" [dll map-function ((byte-code "Â	A\"ˆÃ	Ä	A!\"‡" [map-function dll mapcar setcdr nreverse] 5)) setcdr nreverse] 4))

(defun dll-create-from-list (list) "\
Given an elisp LIST create a doubly linked list with the same elements." (byte-code "ÁB‡" [list DL-LIST] 2))

(defun dll-sort (dll predicate) "\
Sort the doubly linked list DLL, stably, comparing elements using PREDICATE.
Returns the sorted list. DLL is modified by side effects.
PREDICATE is called with two elements of DLL, and should return T
if the first element is \"less\" than the second." (byte-code "ÂÃA	\"\"ˆ‡" [dll predicate setcdr sort] 5))

(defun dll-filter (dll predicate) "\
Remove all elements in the doubly linked list DLL for which PREDICATE
return nil." (byte-code "		A
…% Å
@\"ƒ 
‰‚ Æ
A\"ˆ
A‰ˆ‚ *‡" [prev dll node predicate t funcall setcdr] 5))
