Skip to content

Instantly share code, notes, and snippets.

@wyager
Created March 30, 2017 03:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wyager/8443c3f5a9fc9b52dc28346bafdf409f to your computer and use it in GitHub Desktop.
Save wyager/8443c3f5a9fc9b52dc28346bafdf409f to your computer and use it in GitHub Desktop.
{-# LANGUAGE ScopedTypeVariables #-}
module ADTStorable where
import Foreign.Storable
import Foreign.Ptr
import Data.Word (Word8)
instance forall a . Storable a => Storable (Maybe a) where
sizeOf x = alignment x + sizeOf (undefined :: a)
alignment _ = alignment (undefined :: a)
peek ptr = do
tag <- peek (castPtr ptr :: Ptr Word8)
case tag of
0 -> return Nothing
1 -> do
let ptr' = ptr `plusPtr` alignment (undefined :: Maybe a)
value <- peek (castPtr ptr' :: Ptr a)
return (Just value)
poke ptr Nothing = do
poke (castPtr ptr :: Ptr Word8) 0
poke ptr (Just v) = do
poke (castPtr ptr :: Ptr Word8) 1
let ptr' = ptr `plusPtr` alignment (undefined :: a)
poke (castPtr ptr' :: Ptr a) v
instance forall a b . (Storable a, Storable b) => Storable (Either a b) where
sizeOf x = alignment x + max (sizeOf (undefined :: a)) (sizeOf (undefined :: b))
alignment _ = lcm (alignment (undefined :: a)) (alignment (undefined :: b))
peek ptr = do
tag <- peek (castPtr ptr :: Ptr Word8)
case tag of
0 -> do
let ptr' = ptr `plusPtr` alignment (undefined :: Either a b)
value <- peek (castPtr ptr' :: Ptr a)
return (Left value)
1 -> do
let ptr' = ptr `plusPtr` alignment (undefined :: Either a b)
value <- peek (castPtr ptr' :: Ptr b)
return (Right value)
poke ptr (Left x) = do
poke (castPtr ptr :: Ptr Word8) 0
let ptr' = ptr `plusPtr` alignment (undefined :: Either a b)
poke (castPtr ptr' :: Ptr a) x
poke ptr (Right x) = do
poke (castPtr ptr :: Ptr Word8) 1
let ptr' = ptr `plusPtr` alignment (undefined :: Either a b)
poke (castPtr ptr' :: Ptr b) x
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment