{-# language CPP #-}
{-# language MagicHash #-}
{-# language UnboxedTuples #-}
module Data.Primitive.Addr
(
Addr(..)
, nullAddr
, plusAddr
, minusAddr
, remAddr
, indexOffAddr
, readOffAddr
, writeOffAddr
, copyAddr
#if __GLASGOW_HASKELL__ >= 708
, copyAddrToByteArray
#endif
, moveAddr
, setAddr
, addrToInt
) where
import Numeric (showHex)
import Control.Monad.Primitive
import Data.Primitive.Types (Prim(..))
import Data.Primitive.ByteArray
import GHC.Exts
import GHC.Ptr
import Foreign.Marshal.Utils
#if __GLASGOW_HASKELL__ < 708
toBool# :: Bool -> Bool
toBool# = id
#else
toBool# :: Int# -> Bool
toBool# = isTrue#
#endif
data Addr = Addr Addr#
instance Show Addr where
showsPrec _ (Addr a) =
showString "0x" . showHex (fromIntegral (I# (addr2Int# a)) :: Word)
instance Eq Addr where
Addr a# == Addr b# = toBool# (eqAddr# a# b#)
Addr a# /= Addr b# = toBool# (neAddr# a# b#)
instance Ord Addr where
Addr a# > Addr b# = toBool# (gtAddr# a# b#)
Addr a# >= Addr b# = toBool# (geAddr# a# b#)
Addr a# < Addr b# = toBool# (ltAddr# a# b#)
Addr a# <= Addr b# = toBool# (leAddr# a# b#)
nullAddr :: Addr
nullAddr = Addr nullAddr#
infixl 6 `plusAddr`, `minusAddr`
infixl 7 `remAddr`
plusAddr :: Addr -> Int -> Addr
plusAddr (Addr a#) (I# i#) = Addr (plusAddr# a# i#)
minusAddr :: Addr -> Addr -> Int
minusAddr (Addr a#) (Addr b#) = I# (minusAddr# a# b#)
remAddr :: Addr -> Int -> Int
remAddr (Addr a#) (I# i#) = I# (remAddr# a# i#)
indexOffAddr :: Prim a => Addr -> Int -> a
{-# INLINE indexOffAddr #-}
indexOffAddr (Addr addr#) (I# i#) = indexOffAddr# addr# i#
readOffAddr :: (Prim a, PrimMonad m) => Addr -> Int -> m a
{-# INLINE readOffAddr #-}
readOffAddr (Addr addr#) (I# i#) = primitive (readOffAddr# addr# i#)
writeOffAddr :: (Prim a, PrimMonad m) => Addr -> Int -> a -> m ()
{-# INLINE writeOffAddr #-}
writeOffAddr (Addr addr#) (I# i#) x = primitive_ (writeOffAddr# addr# i# x)
copyAddr :: PrimMonad m
=> Addr
-> Addr
-> Int
-> m ()
{-# INLINE copyAddr #-}
copyAddr (Addr dst#) (Addr src#) n
= unsafePrimToPrim $ copyBytes (Ptr dst#) (Ptr src#) n
#if __GLASGOW_HASKELL__ >= 708
copyAddrToByteArray :: PrimMonad m
=> MutableByteArray (PrimState m)
-> Int
-> Addr
-> Int
-> m ()
{-# INLINE copyAddrToByteArray #-}
copyAddrToByteArray (MutableByteArray marr) (I# off) (Addr addr) (I# len) =
primitive_ $ copyAddrToByteArray# addr marr off len
#endif
moveAddr :: PrimMonad m
=> Addr
-> Addr
-> Int
-> m ()
{-# INLINE moveAddr #-}
moveAddr (Addr dst#) (Addr src#) n
= unsafePrimToPrim $ moveBytes (Ptr dst#) (Ptr src#) n
setAddr :: (Prim a, PrimMonad m) => Addr -> Int -> a -> m ()
{-# INLINE setAddr #-}
setAddr (Addr addr#) (I# n#) x = primitive_ (setOffAddr# addr# 0# n# x)
addrToInt :: Addr -> Int
{-# INLINE addrToInt #-}
addrToInt (Addr addr#) = I# (addr2Int# addr#)