Blame src/extList.ml

rpm-build 0f2925
(*
rpm-build 0f2925
 * ExtList - additional and modified functions for lists.
rpm-build 0f2925
 * Copyright (C) 2003 Brian Hurt
rpm-build 0f2925
 * Copyright (C) 2003 Nicolas Cannasse
rpm-build 0f2925
 * Copyright (C) 2008 Red Hat Inc.
rpm-build 0f2925
 * 
rpm-build 0f2925
 * This library is free software; you can redistribute it and/or
rpm-build 0f2925
 * modify it under the terms of the GNU Lesser General Public
rpm-build 0f2925
 * License as published by the Free Software Foundation; either
rpm-build 0f2925
 * version 2.1 of the License, or (at your option) any later version,
rpm-build 0f2925
 * with the special exception on linking described in file LICENSE.
rpm-build 0f2925
 *
rpm-build 0f2925
 * This library is distributed in the hope that it will be useful,
rpm-build 0f2925
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
rpm-build 0f2925
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
rpm-build 0f2925
 * Lesser General Public License for more details.
rpm-build 0f2925
 *
rpm-build 0f2925
 * You should have received a copy of the GNU Lesser General Public
rpm-build 0f2925
 * License along with this library; if not, write to the Free Software
rpm-build 0f2925
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
rpm-build 0f2925
 *)
rpm-build 0f2925
rpm-build 0f2925
module List = struct
rpm-build 0f2925
rpm-build 0f2925
exception Empty_list
rpm-build 0f2925
exception Invalid_index of int
rpm-build 0f2925
exception Different_list_size of string
rpm-build 0f2925
rpm-build 0f2925
include List
rpm-build 0f2925
rpm-build 0f2925
(* Thanks to Jacques Garrigue for suggesting the following structure *)
rpm-build 0f2925
type 'a mut_list =  {
rpm-build 0f2925
  hd: 'a; 
rpm-build 0f2925
  mutable tl: 'a list
rpm-build 0f2925
}
rpm-build 0f2925
external inj : 'a mut_list -> 'a list = "%identity"
rpm-build 0f2925
rpm-build 0f2925
rpm-build 0f2925
let dummy_node () = { hd = Obj.magic (); tl = [] }
rpm-build 0f2925
rpm-build 0f2925
let hd = function
rpm-build 0f2925
  | [] -> raise Empty_list
rpm-build 0f2925
  | h :: t -> h
rpm-build 0f2925
rpm-build 0f2925
let tl = function
rpm-build 0f2925
  | [] -> raise Empty_list
rpm-build 0f2925
  | h :: t -> t
rpm-build 0f2925
rpm-build 0f2925
let nth l index =
rpm-build 0f2925
  if index < 0 then raise (Invalid_index index);
rpm-build 0f2925
  let rec loop n = function
rpm-build 0f2925
    | [] -> raise (Invalid_index index);
rpm-build 0f2925
    | h :: t ->
rpm-build 0f2925
      if n = 0 then h else loop (n - 1) t
rpm-build 0f2925
  in
rpm-build 0f2925
  loop index l
rpm-build 0f2925
rpm-build 0f2925
let append l1 l2 =
rpm-build 0f2925
  match l1 with
rpm-build 0f2925
  | [] -> l2
rpm-build 0f2925
  | h :: t ->
rpm-build 0f2925
    let rec loop dst = function
rpm-build 0f2925
    | [] ->
rpm-build 0f2925
      dst.tl <- l2
rpm-build 0f2925
    | h :: t ->
rpm-build 0f2925
      let cell = { hd = h; tl = [] } in
rpm-build 0f2925
      dst.tl <- inj cell;
rpm-build 0f2925
      loop cell t
rpm-build 0f2925
    in
rpm-build 0f2925
    let r = { hd = h; tl = [] } in
rpm-build 0f2925
    loop r t;
rpm-build 0f2925
    inj r
rpm-build 0f2925
rpm-build 0f2925
let rec flatten l =
rpm-build 0f2925
  let rec inner dst = function
rpm-build 0f2925
    | [] -> dst
rpm-build 0f2925
    | h :: t ->
rpm-build 0f2925
      let r = { hd = h; tl = [] } in
rpm-build 0f2925
      dst.tl <- inj r;
rpm-build 0f2925
      inner r t
rpm-build 0f2925
  in
rpm-build 0f2925
  let rec outer dst = function
rpm-build 0f2925
    | [] -> ()
rpm-build 0f2925
    | h :: t -> outer (inner dst h) t
rpm-build 0f2925
  in
rpm-build 0f2925
  let r = dummy_node () in
rpm-build 0f2925
  outer r l;
rpm-build 0f2925
  r.tl
rpm-build 0f2925
rpm-build 0f2925
let concat = flatten
rpm-build 0f2925
rpm-build 0f2925
let map f = function
rpm-build 0f2925
  | [] -> []
rpm-build 0f2925
  | h :: t ->
rpm-build 0f2925
    let rec loop dst = function
rpm-build 0f2925
    | [] -> ()
rpm-build 0f2925
    | h :: t ->
rpm-build 0f2925
      let r = { hd = f h; tl = [] } in
rpm-build 0f2925
      dst.tl <- inj r;
rpm-build 0f2925
      loop r t
rpm-build 0f2925
    in
rpm-build 0f2925
    let r = { hd = f h; tl = [] } in
rpm-build 0f2925
    loop r t;
rpm-build 0f2925
    inj r
rpm-build 0f2925
rpm-build 0f2925
let rec drop n = function
rpm-build 0f2925
  | _ :: l when n > 0 -> drop (n-1) l
rpm-build 0f2925
  | l -> l
rpm-build 0f2925
rpm-build 0f2925
let take n l =
rpm-build 0f2925
  let rec loop n dst = function
rpm-build 0f2925
    | h :: t when n > 0 ->
rpm-build 0f2925
      let r = { hd = h; tl = [] } in
rpm-build 0f2925
      dst.tl <- inj r;
rpm-build 0f2925
      loop (n-1) r t
rpm-build 0f2925
    | _ ->
rpm-build 0f2925
      ()
rpm-build 0f2925
  in
rpm-build 0f2925
  let dummy = dummy_node() in
rpm-build 0f2925
  loop n dummy l;
rpm-build 0f2925
  dummy.tl
rpm-build 0f2925
rpm-build 0f2925
(* takewhile and dropwhile by Richard W.M. Jones. *)
rpm-build 0f2925
let rec takewhile f = function
rpm-build 0f2925
  | [] -> []
rpm-build 0f2925
  | x :: xs when f x -> x :: takewhile f xs
rpm-build 0f2925
  | _ -> []
rpm-build 0f2925
rpm-build 0f2925
let rec dropwhile f = function
rpm-build 0f2925
  | [] -> []
rpm-build 0f2925
  | x :: xs when f x -> dropwhile f xs
rpm-build 0f2925
  | xs -> xs
rpm-build 0f2925
rpm-build 0f2925
rpm-build 0f2925
let rec unique ?(cmp = ( = )) l =
rpm-build 0f2925
  let rec loop dst = function
rpm-build 0f2925
    | [] -> ()
rpm-build 0f2925
    | h :: t ->
rpm-build 0f2925
      match exists (cmp h) t with
rpm-build 0f2925
      | true -> loop dst t
rpm-build 0f2925
      | false ->
rpm-build 0f2925
        let r = { hd =  h; tl = [] }  in
rpm-build 0f2925
        dst.tl <- inj r;
rpm-build 0f2925
        loop r t
rpm-build 0f2925
  in
rpm-build 0f2925
  let dummy = dummy_node() in
rpm-build 0f2925
  loop dummy l;
rpm-build 0f2925
  dummy.tl
rpm-build 0f2925
rpm-build 0f2925
let filter_map f l =
rpm-build 0f2925
  let rec loop dst = function
rpm-build 0f2925
    | [] -> ()
rpm-build 0f2925
    | h :: t ->
rpm-build 0f2925
      match f h with
rpm-build 0f2925
      | None -> loop dst t
rpm-build 0f2925
      | Some x ->
rpm-build 0f2925
        let r = { hd = x; tl = [] }  in
rpm-build 0f2925
        dst.tl <- inj r;
rpm-build 0f2925
        loop r t
rpm-build 0f2925
  in
rpm-build 0f2925
  let dummy = dummy_node() in
rpm-build 0f2925
  loop dummy l;
rpm-build 0f2925
  dummy.tl
rpm-build 0f2925
rpm-build 0f2925
let rec find_map f = function
rpm-build 0f2925
  | [] -> raise Not_found
rpm-build 0f2925
  | x :: xs ->
rpm-build 0f2925
      match f x with
rpm-build 0f2925
      | Some y -> y
rpm-build 0f2925
      | None -> find_map f xs
rpm-build 0f2925
rpm-build 0f2925
let fold_right_max = 1000
rpm-build 0f2925
rpm-build 0f2925
let fold_right f l init =
rpm-build 0f2925
  let rec tail_loop acc = function
rpm-build 0f2925
    | [] -> acc
rpm-build 0f2925
    | h :: t -> tail_loop (f h acc) t
rpm-build 0f2925
  in
rpm-build 0f2925
  let rec loop n = function
rpm-build 0f2925
    | [] -> init
rpm-build 0f2925
    | h :: t ->
rpm-build 0f2925
      if n < fold_right_max then
rpm-build 0f2925
        f h (loop (n+1) t)
rpm-build 0f2925
      else
rpm-build 0f2925
        f h (tail_loop init (rev t))
rpm-build 0f2925
  in
rpm-build 0f2925
  loop 0 l
rpm-build 0f2925
rpm-build 0f2925
let map2 f l1 l2 =
rpm-build 0f2925
  let rec loop dst src1 src2 =
rpm-build 0f2925
    match src1, src2 with
rpm-build 0f2925
      | [], [] -> ()
rpm-build 0f2925
      | h1 :: t1, h2 :: t2 ->
rpm-build 0f2925
        let r = { hd = f h1 h2; tl = [] } in
rpm-build 0f2925
        dst.tl <- inj r;
rpm-build 0f2925
        loop r t1 t2
rpm-build 0f2925
      | _ -> raise (Different_list_size "map2")
rpm-build 0f2925
  in
rpm-build 0f2925
  let dummy = dummy_node () in
rpm-build 0f2925
  loop dummy l1 l2;
rpm-build 0f2925
  dummy.tl
rpm-build 0f2925
rpm-build 0f2925
let rev_map2 f l1 l2 =
rpm-build 0f2925
  let rec loop acc l1 l2 =
rpm-build 0f2925
    match l1, l2 with
rpm-build 0f2925
    | [], [] -> acc
rpm-build 0f2925
    | h1 :: t1, h2 :: t2 -> loop (f h1 h2 :: acc) t1 t2
rpm-build 0f2925
    | _ -> raise (Different_list_size "rev_map2")
rpm-build 0f2925
  in
rpm-build 0f2925
  loop [] l1 l2
rpm-build 0f2925
rpm-build 0f2925
let rec iter2 f l1 l2 =
rpm-build 0f2925
  match l1, l2 with
rpm-build 0f2925
  | [], [] -> ()
rpm-build 0f2925
  | h1 :: t1, h2 :: t2 -> f h1 h2; iter2 f t1 t2
rpm-build 0f2925
  | _ -> raise (Different_list_size "iter2")
rpm-build 0f2925
rpm-build 0f2925
let rec fold_left2 f accum l1 l2 =
rpm-build 0f2925
  match l1, l2 with
rpm-build 0f2925
  | [], [] -> accum
rpm-build 0f2925
  | h1 :: t1, h2 :: t2 -> fold_left2 f (f accum h1 h2) t1 t2
rpm-build 0f2925
  | _ -> raise (Different_list_size "fold_left2")
rpm-build 0f2925
rpm-build 0f2925
let fold_right2 f l1 l2 init =
rpm-build 0f2925
  let rec tail_loop acc l1 l2 =
rpm-build 0f2925
    match l1, l2 with
rpm-build 0f2925
    | [] , [] -> acc
rpm-build 0f2925
    | h1 :: t1 , h2 :: t2 -> tail_loop (f h1 h2 acc) t1 t2
rpm-build 0f2925
    | _ -> raise (Different_list_size "fold_right2")
rpm-build 0f2925
  in
rpm-build 0f2925
  let rec loop n l1 l2 =
rpm-build 0f2925
    match l1, l2 with
rpm-build 0f2925
    | [], [] -> init
rpm-build 0f2925
    | h1 :: t1, h2 :: t2 ->
rpm-build 0f2925
      if n < fold_right_max then
rpm-build 0f2925
        f h1 h2 (loop (n+1) t1 t2)
rpm-build 0f2925
      else
rpm-build 0f2925
        f h1 h2 (tail_loop init (rev t1) (rev t2))
rpm-build 0f2925
    | _ -> raise (Different_list_size "fold_right2")
rpm-build 0f2925
  in
rpm-build 0f2925
  loop 0 l1 l2
rpm-build 0f2925
rpm-build 0f2925
let for_all2 p l1 l2 =
rpm-build 0f2925
  let rec loop l1 l2 =
rpm-build 0f2925
    match l1, l2 with
rpm-build 0f2925
    | [], [] -> true
rpm-build 0f2925
    | h1 :: t1, h2 :: t2 -> if p h1 h2 then loop t1 t2 else false
rpm-build 0f2925
    | _ -> raise (Different_list_size "for_all2")
rpm-build 0f2925
  in
rpm-build 0f2925
  loop l1 l2
rpm-build 0f2925
rpm-build 0f2925
let exists2 p l1 l2 =
rpm-build 0f2925
  let rec loop l1 l2 =
rpm-build 0f2925
    match l1, l2 with
rpm-build 0f2925
      | [], [] -> false
rpm-build 0f2925
      | h1 :: t1, h2 :: t2 -> if p h1 h2 then true else loop t1 t2
rpm-build 0f2925
      | _ -> raise (Different_list_size "exists2")
rpm-build 0f2925
  in
rpm-build 0f2925
  loop l1 l2
rpm-build 0f2925
rpm-build 0f2925
let remove_assoc x lst = 
rpm-build 0f2925
  let rec loop dst = function
rpm-build 0f2925
    | [] -> ()
rpm-build 0f2925
    | (a, _ as pair) :: t ->
rpm-build 0f2925
      if a = x then
rpm-build 0f2925
        dst.tl <- t
rpm-build 0f2925
      else
rpm-build 0f2925
        let r = { hd = pair; tl = [] } in
rpm-build 0f2925
        dst.tl <- inj r;
rpm-build 0f2925
        loop r t
rpm-build 0f2925
  in
rpm-build 0f2925
  let dummy = dummy_node () in
rpm-build 0f2925
  loop dummy lst;
rpm-build 0f2925
  dummy.tl
rpm-build 0f2925
rpm-build 0f2925
let remove_assq x lst = 
rpm-build 0f2925
  let rec loop dst = function
rpm-build 0f2925
    | [] -> ()
rpm-build 0f2925
    | (a, _ as pair) :: t ->
rpm-build 0f2925
      if a == x then
rpm-build 0f2925
        dst.tl <- t
rpm-build 0f2925
      else
rpm-build 0f2925
        let r = { hd =  pair; tl = [] } in
rpm-build 0f2925
        dst.tl <- inj r;
rpm-build 0f2925
        loop r t
rpm-build 0f2925
  in
rpm-build 0f2925
  let dummy = dummy_node() in
rpm-build 0f2925
  loop dummy lst;
rpm-build 0f2925
  dummy.tl
rpm-build 0f2925
rpm-build 0f2925
let rfind p l = find p (rev l)
rpm-build 0f2925
rpm-build 0f2925
let find_all p l = 
rpm-build 0f2925
  let rec findnext dst = function
rpm-build 0f2925
    | [] -> ()
rpm-build 0f2925
    | h :: t -> 
rpm-build 0f2925
      if p h then
rpm-build 0f2925
        let r = { hd = h; tl = [] } in
rpm-build 0f2925
        dst.tl <- inj r;
rpm-build 0f2925
        findnext r t
rpm-build 0f2925
      else
rpm-build 0f2925
        findnext dst t
rpm-build 0f2925
  in
rpm-build 0f2925
  let dummy = dummy_node () in
rpm-build 0f2925
  findnext dummy l;
rpm-build 0f2925
  dummy.tl
rpm-build 0f2925
rpm-build 0f2925
let rec findi p l =
rpm-build 0f2925
  let rec loop n = function
rpm-build 0f2925
    | [] -> raise Not_found
rpm-build 0f2925
    | h :: t ->
rpm-build 0f2925
      if p n h then (n,h) else loop (n+1) t
rpm-build 0f2925
  in
rpm-build 0f2925
  loop 0 l
rpm-build 0f2925
rpm-build 0f2925
let filter = find_all
rpm-build 0f2925
rpm-build 0f2925
let partition p lst = 
rpm-build 0f2925
  let rec loop yesdst nodst = function
rpm-build 0f2925
    | [] -> ()
rpm-build 0f2925
    | h :: t ->
rpm-build 0f2925
      let r = { hd = h; tl = [] } in
rpm-build 0f2925
      if p h then
rpm-build 0f2925
        begin
rpm-build 0f2925
          yesdst.tl <- inj r;
rpm-build 0f2925
          loop r nodst t
rpm-build 0f2925
        end
rpm-build 0f2925
      else
rpm-build 0f2925
        begin
rpm-build 0f2925
          nodst.tl <- inj r;
rpm-build 0f2925
          loop yesdst r t
rpm-build 0f2925
        end
rpm-build 0f2925
  in
rpm-build 0f2925
  let yesdummy = dummy_node()
rpm-build 0f2925
  and nodummy = dummy_node()
rpm-build 0f2925
  in
rpm-build 0f2925
  loop yesdummy nodummy lst;
rpm-build 0f2925
  yesdummy.tl, nodummy.tl
rpm-build 0f2925
rpm-build 0f2925
let split lst =
rpm-build 0f2925
  let rec loop adst bdst = function
rpm-build 0f2925
    | [] -> ()
rpm-build 0f2925
    | (a, b) :: t -> 
rpm-build 0f2925
      let x = { hd = a; tl = [] } 
rpm-build 0f2925
      and y = { hd = b; tl = [] } in
rpm-build 0f2925
      adst.tl <- inj x;
rpm-build 0f2925
      bdst.tl <- inj y;
rpm-build 0f2925
      loop x y t
rpm-build 0f2925
  in
rpm-build 0f2925
  let adummy = dummy_node ()
rpm-build 0f2925
  and bdummy = dummy_node ()
rpm-build 0f2925
  in
rpm-build 0f2925
  loop adummy bdummy lst;
rpm-build 0f2925
  adummy.tl, bdummy.tl
rpm-build 0f2925
rpm-build 0f2925
let combine l1 l2 =
rpm-build 0f2925
  let rec loop dst l1 l2 =
rpm-build 0f2925
    match l1, l2 with
rpm-build 0f2925
    | [], [] -> ()
rpm-build 0f2925
    | h1 :: t1, h2 :: t2 -> 
rpm-build 0f2925
      let r = { hd = h1, h2; tl = [] } in
rpm-build 0f2925
      dst.tl <- inj r;
rpm-build 0f2925
      loop r t1 t2
rpm-build 0f2925
    | _, _ -> raise (Different_list_size "combine")
rpm-build 0f2925
  in
rpm-build 0f2925
  let dummy = dummy_node () in
rpm-build 0f2925
  loop dummy l1 l2;
rpm-build 0f2925
  dummy.tl
rpm-build 0f2925
rpm-build 0f2925
let sort ?(cmp=compare) = List.sort cmp
rpm-build 0f2925
rpm-build 0f2925
#if OCAML < 406
rpm-build 0f2925
let rec init size f =
rpm-build 0f2925
  if size = 0 then []
rpm-build 0f2925
  else if size < 0 then invalid_arg "ExtList.init"
rpm-build 0f2925
  else
rpm-build 0f2925
    let rec loop dst n =
rpm-build 0f2925
      if n < size then
rpm-build 0f2925
        let r = { hd = f n; tl = [] } in
rpm-build 0f2925
        dst.tl <- inj r;
rpm-build 0f2925
        loop r (n+1)
rpm-build 0f2925
    in
rpm-build 0f2925
    let r = { hd = f 0; tl = [] } in
rpm-build 0f2925
    loop r 1;
rpm-build 0f2925
    inj r
rpm-build 0f2925
#endif
rpm-build 0f2925
rpm-build 0f2925
let make i x =
rpm-build 0f2925
  if i < 0 then invalid_arg "ExtList.List.make";
rpm-build 0f2925
  let rec loop acc x = function
rpm-build 0f2925
  | 0 -> acc
rpm-build 0f2925
  | i -> loop (x::acc) x (i-1)
rpm-build 0f2925
  in
rpm-build 0f2925
  loop [] x i
rpm-build 0f2925
rpm-build 0f2925
let mapi f = function
rpm-build 0f2925
  | [] -> []
rpm-build 0f2925
  | h :: t ->
rpm-build 0f2925
    let rec loop dst n = function
rpm-build 0f2925
      | [] -> ()
rpm-build 0f2925
      | h :: t ->
rpm-build 0f2925
        let r = { hd = f n h; tl = [] } in
rpm-build 0f2925
        dst.tl <- inj r;
rpm-build 0f2925
        loop r (n+1) t
rpm-build 0f2925
    in
rpm-build 0f2925
    let r = { hd = f 0 h; tl = [] } in
rpm-build 0f2925
    loop r 1 t;
rpm-build 0f2925
    inj r
rpm-build 0f2925
rpm-build 0f2925
#if OCAML < 400
rpm-build 0f2925
let iteri f l =
rpm-build 0f2925
  let rec loop n = function
rpm-build 0f2925
    | [] -> ()
rpm-build 0f2925
    | h :: t ->
rpm-build 0f2925
      f n h;
rpm-build 0f2925
      loop (n+1) t
rpm-build 0f2925
  in
rpm-build 0f2925
  loop 0 l
rpm-build 0f2925
#endif
rpm-build 0f2925
rpm-build 0f2925
let first = hd
rpm-build 0f2925
rpm-build 0f2925
let rec last = function
rpm-build 0f2925
  | [] -> raise Empty_list
rpm-build 0f2925
  | h :: [] -> h
rpm-build 0f2925
  | _ :: t -> last t
rpm-build 0f2925
rpm-build 0f2925
let split_nth index = function
rpm-build 0f2925
  | [] -> if index = 0 then [],[] else raise (Invalid_index index)
rpm-build 0f2925
  | (h :: t as l) ->
rpm-build 0f2925
    if index = 0 then [],l
rpm-build 0f2925
    else if index < 0 then raise (Invalid_index index)
rpm-build 0f2925
    else
rpm-build 0f2925
      let rec loop n dst l =
rpm-build 0f2925
        if n = 0 then l else
rpm-build 0f2925
        match l with
rpm-build 0f2925
        | [] -> raise (Invalid_index index)
rpm-build 0f2925
        | h :: t ->
rpm-build 0f2925
          let r = { hd =  h; tl = [] } in
rpm-build 0f2925
          dst.tl <- inj r;
rpm-build 0f2925
          loop (n-1) r t 
rpm-build 0f2925
      in
rpm-build 0f2925
      let r = { hd = h; tl = [] } in
rpm-build 0f2925
      inj r, loop (index-1) r t
rpm-build 0f2925
rpm-build 0f2925
let find_exc f e l =
rpm-build 0f2925
  try
rpm-build 0f2925
    find f l
rpm-build 0f2925
  with
rpm-build 0f2925
    Not_found -> raise e
rpm-build 0f2925
rpm-build 0f2925
let remove l x =
rpm-build 0f2925
  let rec loop dst = function
rpm-build 0f2925
    | [] -> ()
rpm-build 0f2925
    | h :: t ->
rpm-build 0f2925
      if x = h then 
rpm-build 0f2925
        dst.tl <- t
rpm-build 0f2925
      else
rpm-build 0f2925
        let r = { hd = h; tl = [] } in
rpm-build 0f2925
        dst.tl <- inj r;
rpm-build 0f2925
        loop r t
rpm-build 0f2925
  in
rpm-build 0f2925
  let dummy = dummy_node () in
rpm-build 0f2925
  loop dummy l;
rpm-build 0f2925
  dummy.tl
rpm-build 0f2925
rpm-build 0f2925
let rec remove_if f lst =
rpm-build 0f2925
  let rec loop dst = function
rpm-build 0f2925
    | [] -> ()
rpm-build 0f2925
    | x :: l ->
rpm-build 0f2925
      if f x then
rpm-build 0f2925
        dst.tl <- l
rpm-build 0f2925
      else
rpm-build 0f2925
        let r = { hd = x; tl = [] } in
rpm-build 0f2925
        dst.tl <- inj r;
rpm-build 0f2925
        loop r l
rpm-build 0f2925
  in
rpm-build 0f2925
  let dummy = dummy_node () in
rpm-build 0f2925
  loop dummy lst;
rpm-build 0f2925
  dummy.tl
rpm-build 0f2925
rpm-build 0f2925
let rec remove_all l x =
rpm-build 0f2925
  let rec loop dst = function
rpm-build 0f2925
    | [] -> ()
rpm-build 0f2925
    | h :: t ->
rpm-build 0f2925
      if x = h then
rpm-build 0f2925
        loop dst t
rpm-build 0f2925
      else
rpm-build 0f2925
        let r = { hd = h; tl = [] } in
rpm-build 0f2925
        dst.tl <- inj r;
rpm-build 0f2925
        loop r t
rpm-build 0f2925
  in
rpm-build 0f2925
  let dummy = dummy_node () in
rpm-build 0f2925
  loop dummy l;
rpm-build 0f2925
  dummy.tl
rpm-build 0f2925
rpm-build 0f2925
let enum l =
rpm-build 0f2925
  let rec make lr count =
rpm-build 0f2925
    Enum.make
rpm-build 0f2925
      ~next:(fun () ->
rpm-build 0f2925
        match !lr with
rpm-build 0f2925
        | [] -> raise Enum.No_more_elements
rpm-build 0f2925
        | h :: t ->
rpm-build 0f2925
          decr count;
rpm-build 0f2925
          lr := t;
rpm-build 0f2925
          h
rpm-build 0f2925
      )
rpm-build 0f2925
      ~count:(fun () ->
rpm-build 0f2925
        if !count < 0 then count := length !lr;
rpm-build 0f2925
        !count
rpm-build 0f2925
      )
rpm-build 0f2925
      ~clone:(fun () ->
rpm-build 0f2925
        make (ref !lr) (ref !count)
rpm-build 0f2925
      )
rpm-build 0f2925
  in
rpm-build 0f2925
  make (ref l) (ref (-1))
rpm-build 0f2925
rpm-build 0f2925
let of_enum e =
rpm-build 0f2925
  let h = dummy_node() in
rpm-build 0f2925
  let _ = Enum.fold (fun x acc ->
rpm-build 0f2925
    let r = { hd = x; tl = [] }  in
rpm-build 0f2925
    acc.tl <- inj r;
rpm-build 0f2925
    r) h e in
rpm-build 0f2925
  h.tl
rpm-build 0f2925
rpm-build 0f2925
#if OCAML < 403
rpm-build 0f2925
let cons x l = x :: l
rpm-build 0f2925
#endif
rpm-build 0f2925
rpm-build 0f2925
#if OCAML < 405
rpm-build 0f2925
rpm-build 0f2925
let assoc_opt k l = try Some (assoc k l) with Not_found -> None
rpm-build 0f2925
let assq_opt k l = try Some (assq k l) with Not_found -> None
rpm-build 0f2925
let find_opt p l = try Some (find p l) with Not_found -> None
rpm-build 0f2925
rpm-build 0f2925
let nth_opt =
rpm-build 0f2925
  let rec loop n = function
rpm-build 0f2925
    | [] -> None
rpm-build 0f2925
    | h :: t ->
rpm-build 0f2925
      if n = 0 then Some h else loop (n - 1) t
rpm-build 0f2925
  in
rpm-build 0f2925
  fun l index -> if index < 0 then None else loop index l
rpm-build 0f2925
rpm-build 0f2925
let rec compare_lengths l1 l2 =
rpm-build 0f2925
  match l1, l2 with
rpm-build 0f2925
  | [], [] -> 0
rpm-build 0f2925
  | [], _ -> -1
rpm-build 0f2925
  | _, [] -> 1
rpm-build 0f2925
  | _ :: l1, _ :: l2 -> compare_lengths l1 l2
rpm-build 0f2925
rpm-build 0f2925
let rec compare_length_with l n =
rpm-build 0f2925
  match l, n with
rpm-build 0f2925
  | [], 0 -> 0
rpm-build 0f2925
  | [], _ -> if n > 0 then -1 else 1
rpm-build 0f2925
  | _, 0 -> 1
rpm-build 0f2925
  | _ :: l, n -> compare_length_with l (n-1)
rpm-build 0f2925
rpm-build 0f2925
#endif
rpm-build 0f2925
rpm-build 0f2925
end
rpm-build 0f2925
rpm-build 0f2925
let ( @ ) = List.append