(* * RefList - List reference * Copyright (C) 2003 Nicolas Cannasse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version, * with the special exception on linking described in file LICENSE. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *) open ExtList exception Empty_list exception Invalid_index of int type 'a t = 'a list ref let empty () = ref [] let is_empty x = match !x with | [] -> true | _ -> false let of_list l = ref l let to_list rl = !rl let copy ~dst ~src = dst := !src let copy_list ~dst ~src = dst := src let add rl item = rl := List.append !rl [item] let push rl item = rl := item::!rl let clear rl = rl := [] let length rl = List.length !rl let hd rl = try List.hd !rl with _ -> raise Empty_list let tl rl = try ref (List.tl !rl) with _ -> raise Empty_list let iter f rl = List.iter f !rl let for_all f rl = List.for_all f !rl let map f rl = ref (List.map f !rl) let transform f rl = rl := List.map f !rl let map_list f rl = List.map f !rl let find f rl = List.find f !rl let rev rl = rl := List.rev !rl let find_exc f exn rl = try List.find f !rl with _ -> raise exn let exists f rl = List.exists f !rl let sort ?(cmp=compare) rl = rl := List.sort ~cmp !rl let rfind f rl = List.rfind f !rl let first = hd let last rl = let rec loop = function | x :: [] -> x | x :: l -> loop l | [] -> assert false in match !rl with | [] -> raise Empty_list | l -> loop l let remove rl item = rl := List.remove !rl item let remove_if pred rl = rl := List.remove_if pred !rl let remove_all rl item = rl := List.remove_all !rl item let filter pred rl = rl := List.filter pred !rl let add_sort ?(cmp=compare) rl item = let rec add_aux = function | x::lnext as l -> let r = cmp x item in if r < 0 then item::l else x::(add_aux lnext) | [] -> [item] in rl := add_aux !rl let pop rl = match !rl with | [] -> raise Empty_list | e::l -> rl := l; e let npop rl n = let rec pop_aux l n = if n = 0 then begin rl := l; [] end else match l with | [] -> raise Empty_list | x::l -> x::(pop_aux l (n-1)) in pop_aux !rl n let copy_enum ~dst ~src = dst := List.of_enum src let enum rl = List.enum !rl let of_enum e = ref (List.of_enum e) module Index = struct let remove_at rl pos = let p = ref (-1) in let rec del_aux = function | x::l -> incr p; if !p = pos then l else x::(del_aux l) | [] -> raise (Invalid_index pos) in rl := del_aux !rl let index pred rl = let index = ref (-1) in List.find (fun it -> incr index; pred it; ) !rl; !index let index_of rl item = let index = ref (-1) in List.find (fun it -> incr index; it = item; ) !rl; !index let at_index rl pos = try List.nth !rl pos with _ -> raise (Invalid_index pos) let set rl pos newitem = let p = ref (-1) in rl := List.map (fun item -> incr p; if !p = pos then newitem else item) !rl; if !p < pos || pos < 0 then raise (Invalid_index pos) end