(***********************************************************************)
(*                                                                     *)
(*                         ATS/contrib/atshwxi                         *)
(*                                                                     *)
(***********************************************************************)

(*
** Copyright (C) 2013 Hongwei Xi, ATS Trustful Software, Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and associated documentation files (the "Software"),
** to deal in the Software without restriction, including without limitation
** the rights to use, copy, modify, merge, publish, distribute, sublicense,
** and/or sell copies of the Software, and to permit persons to whom the
** Software is furnished to do so, subject to the following stated conditions:
** 
** The above copyright notice and this permission notice shall be included in
** all copies or substantial portions of the Software.
** 
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
** FROM OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
** IN THE SOFTWARE.
*)

(* ****** ****** *)

(*
abst@ype T
*)

(* ****** ****** *)

extern fun get (): T
extern fun set (x: T): void
extern fun getref (): [l:addr] vtakeoutptr (T)

(* ****** ****** *)

local

var _val: T
val p_val = addr@(_val)
prval pf_val = view@(_val)
val () = initize (!p_val)

val r_val =
  ref_make_viewptr{T}(pf_val | p_val)
// end of [val]

in (* in of [local] *)

implement get () = !r_val
implement set (x) = !r_val := x

(* ****** ****** *)

implement
getref () = let
//
extern
praxi
__assert{l:addr}
  (ptr: ptr (l)): vtakeout0 (T@l)
//
prval (pf, fpf) = __assert (p_val)
//
in
  (pf, fpf | p_val)
end // end of [getref]

end // end of [local]

(* ****** ****** *)

(* end of [globvar.hats] *)
