module Data.Enum.Storable ( T, fromPlain, toPlain, ) where import Foreign.Storable (Storable, poke, peek, sizeOf, alignment) import Foreign.Ptr (Ptr, castPtr) import Data.Functor ((<$>)) import Prelude2010 import Prelude () newtype T w e = Cons e deriving (Eq, Ord) instance (Show e) => Show (T w e) where showsPrec p (Cons e) = showParen (p>=10) $ showString "Enum.fromPlain " . showsPrec 11 e instance (Bounded e) => Bounded (T w e) where minBound = Cons minBound maxBound = Cons maxBound instance (Enum e) => Enum (T w e) where fromEnum (Cons e) = fromEnum e toEnum = Cons . toEnum succ (Cons e) = Cons $ succ e pred (Cons e) = Cons $ pred e enumFrom (Cons e) = map Cons $ enumFrom e enumFromThen (Cons e0) (Cons e1) = map Cons $ enumFromThen e0 e1 enumFromTo (Cons e0) (Cons e1) = map Cons $ enumFromTo e0 e1 enumFromThenTo (Cons e0) (Cons e1) (Cons e2) = map Cons $ enumFromThenTo e0 e1 e2 enumPtr :: Ptr (T w e) -> Ptr w enumPtr = castPtr zero :: (Num w) => T w e -> w zero _ = 0 instance (Storable w, Integral w, Enum e) => Storable (T w e) where sizeOf = sizeOf . zero alignment = alignment . zero peek ptr = Cons . toEnum . fromIntegral <$> peek (enumPtr ptr) poke ptr (Cons e) = poke (enumPtr ptr) (fromIntegral $ fromEnum e) fromPlain :: a -> T w a fromPlain = Cons toPlain :: T w a -> a toPlain (Cons a) = a