reinterpret-cast-0.1.0: src/Data/ReinterpretCast/Internal/ImplFFI.hs
-- | This is the 'FFI' approach.
--
-- Implements casting via the FFI, using `alloca` like in
-- <http://hackage.haskell.org/package/data-binary-ieee754>.
module Data.ReinterpretCast.Internal.ImplFFI
( floatToWord
, wordToFloat
, doubleToWord
, wordToDouble
) where
import qualified Foreign as F
import System.IO.Unsafe (unsafePerformIO)
-- | Reinterpret-casts a `Float` to a `F.Word32`.
floatToWord :: Float -> F.Word32
floatToWord = fromFloat
{-# INLINABLE floatToWord #-}
-- | Reinterpret-casts a `F.Word32` to a `Float`.
wordToFloat :: F.Word32 -> Float
wordToFloat = toFloat
{-# INLINABLE wordToFloat #-}
-- | Reinterpret-casts a `Double` to a `F.Word64`.
doubleToWord :: Double -> F.Word64
doubleToWord = fromFloat
{-# INLINABLE doubleToWord #-}
-- | Reinterpret-casts a `F.Word64` to a `Double`.
wordToDouble :: F.Word64 -> Double
wordToDouble = toFloat
{-# INLINABLE wordToDouble #-}
toFloat :: (F.Storable word, F.Storable float) => word -> float
toFloat word = unsafePerformIO $ F.alloca $ \buf -> do
F.poke (F.castPtr buf) word
F.peek buf
{-# INLINE toFloat #-}
fromFloat :: (F.Storable word, F.Storable float) => float -> word
fromFloat float = unsafePerformIO $ F.alloca $ \buf -> do
F.poke (F.castPtr buf) float
F.peek buf
{-# INLINE fromFloat #-}