{-# LANGUAGE FlexibleContexts #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
-- |
-- Module      : Foreign.Prim.StablePtr
-- Copyright   : (c) Alexey Kuleshevich 2020
-- License     : BSD3
-- Maintainer  : Alexey Kuleshevich <alexey@kuleshevi.ch>
-- Stability   : experimental
-- Portability : non-portable
--
module Foreign.Prim.StablePtr
  ( GHC.StablePtr(..)
  , newStablePtr
  , deRefStablePtr
  , freeStablePtr
  , GHC.castStablePtrToPtr
  , GHC.castPtrToStablePtr
  ) where

import Control.DeepSeq
import Control.Prim.Monad
import qualified GHC.Stable as GHC

instance NFData (GHC.StablePtr a) where
  rnf :: StablePtr a -> ()
rnf (GHC.StablePtr StablePtr# a
_) = ()

instance Show (GHC.StablePtr a) where
  show :: StablePtr a -> String
show = Ptr () -> String
forall a. Show a => a -> String
show (Ptr () -> String)
-> (StablePtr a -> Ptr ()) -> StablePtr a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StablePtr a -> Ptr ()
forall a. StablePtr a -> Ptr ()
GHC.castStablePtrToPtr


-- | Same as `GHC.newStablePtr`, but generalized to `MonadPrim`
newStablePtr :: MonadPrim RW m => a -> m (GHC.StablePtr a)
newStablePtr :: a -> m (StablePtr a)
newStablePtr = IO (StablePtr a) -> m (StablePtr a)
forall s (n :: * -> *) (m :: * -> *) a.
(MonadPrimBase s n, MonadPrim s m) =>
n a -> m a
liftPrimBase (IO (StablePtr a) -> m (StablePtr a))
-> (a -> IO (StablePtr a)) -> a -> m (StablePtr a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> IO (StablePtr a)
forall a. a -> IO (StablePtr a)
GHC.newStablePtr

-- | Same as `GHC.deRefStablePtr`, but generalized to `MonadPrim`
deRefStablePtr :: MonadPrim RW m => GHC.StablePtr a -> m a
deRefStablePtr :: StablePtr a -> m a
deRefStablePtr = IO a -> m a
forall s (n :: * -> *) (m :: * -> *) a.
(MonadPrimBase s n, MonadPrim s m) =>
n a -> m a
liftPrimBase (IO a -> m a) -> (StablePtr a -> IO a) -> StablePtr a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StablePtr a -> IO a
forall a. StablePtr a -> IO a
GHC.deRefStablePtr

-- | Same as `GHC.freeStablePtr`, but generalized to `MonadPrim`
freeStablePtr :: MonadPrim RW m => GHC.StablePtr a -> m ()
freeStablePtr :: StablePtr a -> m ()
freeStablePtr = IO () -> m ()
forall s (n :: * -> *) (m :: * -> *) a.
(MonadPrimBase s n, MonadPrim s m) =>
n a -> m a
liftPrimBase (IO () -> m ()) -> (StablePtr a -> IO ()) -> StablePtr a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StablePtr a -> IO ()
forall a. StablePtr a -> IO ()
GHC.freeStablePtr