include Queue


let take_opt q =
  try Some (take q)
  with Empty -> raise Empty

let peek_opt q =
  try Some (peek q)
  with Empty -> raise Empty




(*
type 'a cell =
  | Nil
  | Cons of { content: 'a; mutable next: 'a cell }

type 'a internal = {
  mutable length: int;
  mutable first: 'a cell;
  mutable last: 'a cell
}

let to_seq (q : 'a t) =
  let q : 'a internal = Obj.magic q in
  let rec aux c () = match c with
    | Nil -> Stdcompat__seq.Nil
    | Cons { content=x; next; } -> Stdcompat__seq.Cons (x, aux next)
  in
  aux q.first
*)

type 'a cell = {
    content: 'a;
    mutable next: 'a cell
  }

type 'a internal = {
    mutable length: int;
    mutable tail: 'a cell
  }

let to_seq (q : 'a t) =
  let q : 'a internal = Obj.magic q in
  if q.length = 0 then
    Stdcompat__seq.empty
  else
    begin
      let tail = q.tail in
      let rec aux cell () =
        let tail' =
          if cell == tail then
            Stdcompat__seq.empty
          else
            aux cell.next in
        Stdcompat__seq.Cons (cell.content, tail') in
      aux tail.next
    end


(*
let to_list q =
  fold (fun accu content -> content :: accu) [] q

let to_seq q =
  Stdcompat__list.to_seq (List.rev (to_list q))
*)

let add_seq q i = Stdcompat__seq.iter (fun x -> push x q) i

let of_seq g =
  let q = create() in
  add_seq q g;
  q

