{-# LANGUAGE MagicHash, UnboxedTuples, GHCForeignImportPrim, UnliftedFFITypes, BangPatterns #-}
-- | This module allows for the (obviously unsafe) overwriting of one haskell value with another.
module Data.ListBuilder.Unsafe (
     unsafeSetField
  ,  unsafeGetField
  ) where

import GHC.Prim
import GHC.Exts

foreign import prim "unsafeSetFieldzh" unsafeSetField# :: Int# -> Any -> Any -> (##)
foreign import prim "unsafeGetFieldzh" unsafeGetField# :: Int# -> Any -> (# Any #)

-- Set the value of a certain constructor field.
-- You'd better be careful that it isn't being shared
unsafeSetField :: Int -> a -> b -> IO ()
unsafeSetField :: forall a b. Int -> a -> b -> IO ()
unsafeSetField (I# Int#
i) !a
x b
y = case Int# -> Any -> Any -> (# #)
unsafeSetField# Int#
i (a -> Any
forall a b. a -> b
unsafeCoerce# a
x :: Any) (b -> Any
forall a b. a -> b
unsafeCoerce# b
y :: Any) of
  (##) -> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
{-# INLINE unsafeSetField #-}

unsafeGetField :: Int -> a -> IO b
unsafeGetField :: forall a b. Int -> a -> IO b
unsafeGetField (I# Int#
i) !a
x = case Int# -> Any -> (# Any #)
unsafeGetField# Int#
i (a -> Any
forall a b. a -> b
unsafeCoerce# a
x :: Any) of
  (# Any
y #) -> b -> IO b
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Any -> b
forall a b. a -> b
unsafeCoerce# Any
y)
{-# INLINE unsafeGetField #-}