    {-# LANGUAGE MagicHash,FlexibleInstances,BangPatterns,CPP #-}
    module Data.Static where

    import GHC.Exts
    import GHC.Prim
    import GHC.Word
    import Data.Word
    import Data.Bits
    import Data.Char

    class StaticElement e where
        extract :: Addr# -> Int# -> e
        gen :: e -> [Word8]

    instance StaticElement Word8 where
        extract :: Addr# -> Int# -> Word8
    extract Addr#
    addr Int#
    i = Word8# -> Word8
    W8# (Addr# -> Int# -> Word8#
    indexWord8OffAddr# Addr#
    addr Int#
    i)
        gen :: Word8 -> [Word8]
    gen Word8
    w = [Word8
    w]

    instance StaticElement Word16 where
        extract :: Addr# -> Int# -> Word16
    extract Addr#
    addr Int#
    i = Word16# -> Word16
    W16# (Addr# -> Int# -> Word16#
    indexWord16OffAddr# Addr#
    addr Int#
    i)
        gen :: Word16 -> [Word8]
    gen Word16
    w = let r1 :: Word8
    r1 = Word16 -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word16
    w
                    r2 :: Word8
    r2 = Word16 -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Word16 -> Word8) -> Word16 -> Word8
    forall a b. (a -> b) -> a -> b
    $ Word16
    w Word16 -> Int -> Word16
    forall a. Bits a => a -> Int -> a
    `shiftR` Int
    8
                in [Word8
    r1,Word8
    r2]

    instance StaticElement Word32 where
        extract :: Addr# -> Int# -> Word32
    extract Addr#
    addr Int#
    i = Word32# -> Word32
    W32# (Addr# -> Int# -> Word32#
    indexWord32OffAddr# Addr#
    addr Int#
    i)
        gen :: Word32 -> [Word8]
    gen Word32
    w = let r1 :: Word8
    r1 = Word32 -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word32
    w
                    r2 :: Word8
    r2 = Word32 -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Word32 -> Word8) -> Word32 -> Word8
    forall a b. (a -> b) -> a -> b
    $ Word32
    w Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `shiftR`  Int
    8
                    r3 :: Word8
    r3 = Word32 -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Word32 -> Word8) -> Word32 -> Word8
    forall a b. (a -> b) -> a -> b
    $ Word32
    w Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `shiftR` Int
    16
                    r4 :: Word8
    r4 = Word32 -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Word32 -> Word8) -> Word32 -> Word8
    forall a b. (a -> b) -> a -> b
    $ Word32
    w Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `shiftR` Int
    24
                in [Word8
    r1,Word8
    r2,Word8
    r3,Word8
    r4]

    instance StaticElement Char where
        extract :: Addr# -> Int# -> Char
    extract Addr#
    addr Int#
    i = Char# -> Char
    C# (Addr# -> Int# -> Char#
    indexWideCharOffAddr# Addr#
    addr Int#
    i)
        gen :: Char -> [Word8]
    gen Char
    c = Word32 -> [Word8]
    forall e. StaticElement e => e -> [Word8]
    gen (Int -> Word32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Char -> Int
    ord Char
    c)::Word32)

    instance StaticElement (Maybe Char) where
        extract :: Addr# -> Int# -> Maybe Char
    extract Addr#
    addr Int#
    i = let !v :: Word32#
    v = Addr# -> Int# -> Word32#
    indexWord32OffAddr# Addr#
    addr Int#
    i
    #if __GLASGOW_HASKELL__ < 708
                         in if eqWord# v (int2Word# 4294967295#) -- -1 in Word32
    #elif __GLASGOW_HASKELL__ < 902
                         in if isTrue# (eqWord# v (int2Word# 4294967295#)) -- -1 in Word32
    #else
                         in if Int# -> Bool
    isTrue# (Word32# -> Word32# -> Int#
    eqWord32# Word32#
    v (Word# -> Word32#
    wordToWord32# (Int# -> Word#
    int2Word# Int#
    4294967295#))) -- -1 in Word32
    #endif
                            then Maybe Char
    forall a. Maybe a
    Nothing
    #if __GLASGOW_HASKELL__ < 902
                            else (if (I# (word2Int# v)) > 0x10FFFF
                                  then error (show (I# (word2Int# v))++" is not a valid char ("++show (I# i)++")")
                                  else Just (chr (I# (word2Int# v)))
                                 )
    #else
                            else (if (Int# -> Int
    I# (Int32# -> Int#
    int32ToInt# (Word32# -> Int32#
    word32ToInt32# Word32#
    v))) Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    0x10FFFF
                                  then [Char] -> Maybe Char
    forall a. HasCallStack => [Char] -> a
    error (Int -> [Char]
    forall a. Show a => a -> [Char]
    show (Int# -> Int
    I# (Int32# -> Int#
    int32ToInt# (Word32# -> Int32#
    word32ToInt32# Word32#
    v)))[Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++[Char]
    " is not a valid char ("[Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++Int -> [Char]
    forall a. Show a => a -> [Char]
    show (Int# -> Int
    I# Int#
    i)[Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++[Char]
    ")")
                                  else Char -> Maybe Char
    forall a. a -> Maybe a
    Just (Int -> Char
    chr (Int# -> Int
    I#  (Int32# -> Int#
    int32ToInt# (Word32# -> Int32#
    word32ToInt32# Word32#
    v))))
                                 )
    #endif

        gen :: Maybe Char -> [Word8]
    gen Maybe Char
    Nothing = Word32 -> [Word8]
    forall e. StaticElement e => e -> [Word8]
    gen (Word32 -> Word32
    forall a. Bits a => a -> a
    complement (Word32
    0 :: Word32))
        gen (Just Char
    c) = Word32 -> [Word8]
    forall e. StaticElement e => e -> [Word8]
    gen (Int -> Word32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Char -> Int
    ord Char
    c)::Word32)

    instance StaticElement a => StaticElement (a,a) where
        extract :: Addr# -> Int# -> (a, a)
    extract Addr#
    addr Int#
    i = let x1 :: a
    x1 = Addr# -> Int# -> a
    forall e. StaticElement e => Addr# -> Int# -> e
    extract Addr#
    addr (Int#
    i Int# -> Int# -> Int#
    *# Int#
    2#)
                             x2 :: a
    x2 = Addr# -> Int# -> a
    forall e. StaticElement e => Addr# -> Int# -> e
    extract Addr#
    addr (Int#
    i Int# -> Int# -> Int#
    *# Int#
    2# Int# -> Int# -> Int#
    +# Int#
    1#)
                         in (a
    x1,a
    x2)
        gen :: (a, a) -> [Word8]
    gen (a
    x1,a
    x2) = a -> [Word8]
    forall e. StaticElement e => e -> [Word8]
    gen a
    x1 [Word8] -> [Word8] -> [Word8]
    forall a. [a] -> [a] -> [a]
    ++ a -> [Word8]
    forall e. StaticElement e => e -> [Word8]
    gen a
    x2

    instance StaticElement a => StaticElement (a,a,a) where
        extract :: Addr# -> Int# -> (a, a, a)
    extract Addr#
    addr Int#
    i = let x1 :: a
    x1 = Addr# -> Int# -> a
    forall e. StaticElement e => Addr# -> Int# -> e
    extract Addr#
    addr (Int#
    i Int# -> Int# -> Int#
    *# Int#
    3#)
                             x2 :: a
    x2 = Addr# -> Int# -> a
    forall e. StaticElement e => Addr# -> Int# -> e
    extract Addr#
    addr (Int#
    i Int# -> Int# -> Int#
    *# Int#
    3# Int# -> Int# -> Int#
    +# Int#
    1#)
                             x3 :: a
    x3 = Addr# -> Int# -> a
    forall e. StaticElement e => Addr# -> Int# -> e
    extract Addr#
    addr (Int#
    i Int# -> Int# -> Int#
    *# Int#
    3# Int# -> Int# -> Int#
    +# Int#
    2#)
                         in (a
    x1,a
    x2,a
    x3)
        gen :: (a, a, a) -> [Word8]
    gen (a
    x1,a
    x2,a
    x3) = a -> [Word8]
    forall e. StaticElement e => e -> [Word8]
    gen a
    x1 [Word8] -> [Word8] -> [Word8]
    forall a. [a] -> [a] -> [a]
    ++ a -> [Word8]
    forall e. StaticElement e => e -> [Word8]
    gen a
    x2 [Word8] -> [Word8] -> [Word8]
    forall a. [a] -> [a] -> [a]
    ++ a -> [Word8]
    forall e. StaticElement e => e -> [Word8]
    gen a
    x3

    instance StaticElement a => StaticElement (a,a,a,a) where
        extract :: Addr# -> Int# -> (a, a, a, a)
    extract Addr#
    addr Int#
    i = let x1 :: a
    x1 = Addr# -> Int# -> a
    forall e. StaticElement e => Addr# -> Int# -> e
    extract Addr#
    addr (Int#
    i Int# -> Int# -> Int#
    *# Int#
    4#)
                             x2 :: a
    x2 = Addr# -> Int# -> a
    forall e. StaticElement e => Addr# -> Int# -> e
    extract Addr#
    addr (Int#
    i Int# -> Int# -> Int#
    *# Int#
    4# Int# -> Int# -> Int#
    +# Int#
    1#)
                             x3 :: a
    x3 = Addr# -> Int# -> a
    forall e. StaticElement e => Addr# -> Int# -> e
    extract Addr#
    addr (Int#
    i Int# -> Int# -> Int#
    *# Int#
    4# Int# -> Int# -> Int#
    +# Int#
    2#)
                             x4 :: a
    x4 = Addr# -> Int# -> a
    forall e. StaticElement e => Addr# -> Int# -> e
    extract Addr#
    addr (Int#
    i Int# -> Int# -> Int#
    *# Int#
    4# Int# -> Int# -> Int#
    +# Int#
    3#)
                         in (a
    x1,a
    x2,a
    x3,a
    x4)
        gen :: (a, a, a, a) -> [Word8]
    gen (a
    x1,a
    x2,a
    x3,a
    x4) = a -> [Word8]
    forall e. StaticElement e => e -> [Word8]
    gen a
    x1 [Word8] -> [Word8] -> [Word8]
    forall a. [a] -> [a] -> [a]
    ++ a -> [Word8]
    forall e. StaticElement e => e -> [Word8]
    gen a
    x2 [Word8] -> [Word8] -> [Word8]
    forall a. [a] -> [a] -> [a]
    ++ a -> [Word8]
    forall e. StaticElement e => e -> [Word8]
    gen a
    x3 [Word8] -> [Word8] -> [Word8]
    forall a. [a] -> [a] -> [a]
    ++ a -> [Word8]
    forall e. StaticElement e => e -> [Word8]
    gen a
    x4