{-# 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 = Word# -> Word8
W8# (Addr# -> Int# -> Word#
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 = Word# -> Word16
W16# (Addr# -> Int# -> Word#
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 = Word# -> Word32
W32# (Addr# -> Int# -> Word#
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 :: Word#
v = Addr# -> Int# -> Word#
indexWord32OffAddr# Addr#
addr Int#
i
#if __GLASGOW_HASKELL__ >= 708
                     in if Int# -> Bool
isTrue# (Word# -> Word# -> Int#
eqWord# Word#
v (Int# -> Word#
int2Word# Int#
4294967295#)) -- -1 in Word32
#else
                     in if eqWord# v (int2Word# 4294967295#) -- -1 in Word32
#endif
                        then Maybe Char
forall a. Maybe a
Nothing
                        else (if (Int# -> Int
I# (Word# -> Int#
word2Int# Word#
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# (Word# -> Int#
word2Int# Word#
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# (Word# -> Int#
word2Int# Word#
v)))
                             )
    gen :: Maybe Char -> [Word8]
gen Maybe Char
Nothing = Word32 -> [Word8]
forall e. StaticElement e => e -> [Word8]
gen (-Word32
1::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