Flatten the sources, only leave the XPath module packed.
[tatoo.git] / src / hlist.ml
diff --git a/src/hlist.ml b/src/hlist.ml
new file mode 100644 (file)
index 0000000..3ffb8fc
--- /dev/null
@@ -0,0 +1,82 @@
+INCLUDE "utils.ml"
+
+include Hlist_sig
+
+module type HConsBuilder =
+  functor (H : Common_sig.HashedType) -> Hcons.S with type data = H.t
+
+module Builder (HCB : HConsBuilder) (H : Hcons.Abstract) :
+  S with type elt = H.t =
+struct
+  type elt = H.t
+
+  module rec Node : Hcons.S with type data = Data.t = HCB(Data)
+                            and Data : Common_sig.HashedType with type t = (elt, Node.t) node =
+  struct
+    type t = (elt, Node.t) node
+    let equal x y =
+      match x,y with
+      | Nil, Nil -> true
+      | Cons(e1, l1), Cons(e2, l2) -> e1 == e2 && l1 == l2
+      | _ -> false
+
+    let hash = function
+    | Nil -> 0
+    | Cons(e, l) -> HASHINT3 (PRIME1, Uid.to_int (H.uid e), Uid.to_int (Node.uid l))
+  end
+
+  include Node
+
+  let nil = make Nil
+
+  let rec sorted_cons e l =
+    match l.Node.node with
+      |        Nil -> Node.make (Cons(e, l))
+      | Cons (x, ll) ->
+         if H.uid e < H.uid x
+         then Node.make (Cons(e, l))
+         else Node.make (Cons(x, sorted_cons e ll))
+
+  let cons e l =
+    Node.make(Cons(e, l))
+
+  let cons ?(sorted=true) e l =
+    if sorted then sorted_cons e l else cons e l
+
+  let hd = function { Node.node = Cons(e, _); _ } -> e | _ -> failwith "hd"
+  let tl = function { Node.node = Cons(_, l); _ } -> l | _ -> failwith "tl"
+
+  let fold f l acc =
+    let rec loop acc l = match l.Node.node with
+      | Nil -> acc
+      | Cons (a, aa) -> loop (f a acc) aa
+    in
+      loop acc l
+
+  let map f l  =
+    let rec loop l = match l.Node.node with
+      | Nil -> nil
+      | Cons(a, aa) -> cons (f a) (loop aa)
+    in
+      loop l
+
+  let iter f l =
+    let rec loop l = match l.Node.node with
+      | Nil -> ()
+      | Cons(a,aa) ->  (f a);(loop aa)
+    in
+      loop l
+
+  let rev l = fold cons l nil
+  let rev_map f l = fold (fun x acc -> cons (f x) acc) l nil
+  let length l = fold (fun _ c -> c+1) l 0
+  let rec mem e l =
+    match l.Node.node with
+      | Nil -> false
+      | Cons (x, ll) -> x == e || mem e ll
+
+end
+
+module Make = Builder(Hcons.Make)
+module Weak = Builder(Hcons.Weak)
+