-- | This is the 'FFI' approach. -- -- Implements casting via the FFI, using `alloca` like in -- . 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 #-}