(********************************************************************)
(*                                                                  *)
(*  The Why3 Verification Platform   /   The Why3 Development Team  *)
(*  Copyright 2010-2017   --   INRIA - CNRS - Paris-Sud University  *)
(*                                                                  *)
(*  This software is distributed under the terms of the GNU Lesser  *)
(*  General Public License version 2.1, with the special exception  *)
(*  on linking described in file LICENSE.                           *)
(*                                                                  *)
(********************************************************************)

(* useful option combinators *)

let pp pp fmt = function
  | None -> Format.fprintf fmt "None"
  | Some q -> Format.fprintf fmt "Some %a" pp q

let get = function None -> invalid_arg "Opt.get" | Some x -> x

let get_exn exn = function None -> raise exn | Some x -> x

let get_def d = function None -> d | Some x -> x

let map f = function None -> None | Some x -> Some (f x)

let apply d f x = match f with None -> d | Some f -> f x

let apply2 d f x y = match f with None -> d | Some f -> f x y

let bind f = function None -> None | Some x -> f x

let fold f d = function None -> d | Some x -> f d x

let fold_right f o d = match o with None -> d | Some x -> f x d

let for_all f = function None -> true | Some x -> f x

let iter f = function None -> () | Some x -> f x

let map2 f x y = match x,y with
  | None, None -> None
  | Some x, Some y -> Some (f x y)
  | _ -> None

let equal eq a b = match a,b with
  | None, None -> true
  | None, _ | _, None -> false
  | Some x, Some y -> eq x y

let compare cmp a b = match a,b with
  | None, None -> 0
  | None, Some _ -> -1
  | Some _, None -> 1
  | Some x, Some y -> cmp x y

let map_fold f acc x = match x with
  | None -> acc, None
  | Some x -> let acc, x = f acc x in acc, Some x
