module Data.Repa.Convert.Format.App
        (App (..))
where
import Data.Repa.Convert.Internal.Format
import Data.Repa.Convert.Internal.Packable
import Data.Repa.Convert.Internal.Packer
import Data.Repa.Scalar.Product
import Data.Monoid
import Prelude hiding (fail)
#include "repa-convert.h"


-- | Append fields without separators.
data App f = App f         


instance Format (App ()) where
 type Value (App ())    = ()
 fieldCount :: App () -> Int
fieldCount (App ())    = Int
0
 minSize :: App () -> Int
minSize    (App ())    = Int
0
 fixedSize :: App () -> Maybe Int
fixedSize  (App ())    = Int -> Maybe Int
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return Int
0
 packedSize :: App () -> Value (App ()) -> Maybe Int
packedSize (App ()) () = Int -> Maybe Int
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return Int
0
 {-# INLINE minSize    #-}
 {-# INLINE fieldCount #-}
 {-# INLINE fixedSize  #-}
 {-# INLINE packedSize #-}


instance ( Format f1, Format (App fs)
         , Value (App fs) ~ Value fs)
      =>  Format (App (f1 :*: fs)) where
 type Value (App (f1 :*: fs))   
        = Value f1 :*: Value fs

 minSize :: App (f1 :*: fs) -> Int
minSize    (App (f1
f1  :*: fs
fs))
  = f1 -> Int
forall f. Format f => f -> Int
minSize f1
f1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ App fs -> Int
forall f. Format f => f -> Int
minSize (fs -> App fs
forall f. f -> App f
App fs
fs)
 {-# NOINLINE minSize    #-}

 fieldCount :: App (f1 :*: fs) -> Int
fieldCount (App (f1
_f1 :*: fs
fs))
  = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ App fs -> Int
forall f. Format f => f -> Int
fieldCount (fs -> App fs
forall f. f -> App f
App fs
fs)
 {-# NOINLINE fieldCount #-}

 fixedSize :: App (f1 :*: fs) -> Maybe Int
fixedSize  (App (f1
f1 :*: fs
fs))
  = do  Int
s1      <- f1 -> Maybe Int
forall f. Format f => f -> Maybe Int
fixedSize f1
f1
        Int
ss      <- App fs -> Maybe Int
forall f. Format f => f -> Maybe Int
fixedSize (fs -> App fs
forall f. f -> App f
App fs
fs)
        Int -> Maybe Int
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return  (Int -> Maybe Int) -> Int -> Maybe Int
forall a b. (a -> b) -> a -> b
$ Int
s1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
ss
 {-# NOINLINE fixedSize  #-}

 packedSize :: App (f1 :*: fs) -> Value (App (f1 :*: fs)) -> Maybe Int
packedSize (App (f1
f1 :*: fs
fs)) (Value f1
x1 :*: Value fs
xs)
  = do  Int
s1      <- f1 -> Value f1 -> Maybe Int
forall f. Format f => f -> Value f -> Maybe Int
packedSize f1
f1       Value f1
x1
        Int
ss      <- App fs -> Value (App fs) -> Maybe Int
forall f. Format f => f -> Value f -> Maybe Int
packedSize (fs -> App fs
forall f. f -> App f
App fs
fs) Value fs
Value (App fs)
xs
        Int -> Maybe Int
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return  (Int -> Maybe Int) -> Int -> Maybe Int
forall a b. (a -> b) -> a -> b
$ Int
s1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
ss
 {-# NOINLINE packedSize #-}


instance Packable (App ()) where
 packer :: App ()
-> Value (App ()) -> Addr# -> IO () -> (Addr# -> IO ()) -> IO ()
packer App ()
_f Value (App ())
_v Addr#
start IO ()
_fails Addr# -> IO ()
eat
        = Addr# -> IO ()
eat Addr#
start
 {-# INLINE packer #-}
 

instance Unpackable (App ()) where
 unpacker :: App ()
-> Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> Value (App ()) -> IO ())
-> IO ()
unpacker App ()
_f Addr#
start Addr#
_end Word8 -> Bool
_stop IO ()
_fails Addr# -> Value (App ()) -> IO ()
eat
        = Addr# -> Value (App ()) -> IO ()
eat Addr#
start ()
 {-# INLINE unpacker #-}


instance ( Packable f1, Packable (App fs)
         , Value (App fs) ~ Value fs)
      => Packable (App (f1 :*: fs)) where

 pack :: App (f1 :*: fs) -> Value (App (f1 :*: fs)) -> Packer
pack    (App (f1
f1 :*: fs
fs)) (Value f1
x1 :*: Value fs
xs)
  =     f1 -> Value f1 -> Packer
forall format. Packable format => format -> Value format -> Packer
pack f1
f1 Value f1
x1 Packer -> Packer -> Packer
forall a. Semigroup a => a -> a -> a
<> App fs -> Value (App fs) -> Packer
forall format. Packable format => format -> Value format -> Packer
pack (fs -> App fs
forall f. f -> App f
App fs
fs) Value fs
Value (App fs)
xs
 {-# NOINLINE pack #-}

 packer :: App (f1 :*: fs)
-> Value (App (f1 :*: fs))
-> Addr#
-> IO ()
-> (Addr# -> IO ())
-> IO ()
packer  App (f1 :*: fs)
f Value (App (f1 :*: fs))
v
  = Packer -> Addr# -> IO () -> (Addr# -> IO ()) -> IO ()
fromPacker (Packer -> Addr# -> IO () -> (Addr# -> IO ()) -> IO ())
-> Packer -> Addr# -> IO () -> (Addr# -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ App (f1 :*: fs) -> Value (App (f1 :*: fs)) -> Packer
forall format. Packable format => format -> Value format -> Packer
pack App (f1 :*: fs)
f Value (App (f1 :*: fs))
v
 {-# INLINE packer #-}


instance ( Unpackable f1, Unpackable (App fs)
         , Value (App fs) ~ Value fs)
      => Unpackable (App (f1 :*: fs)) where

 unpacker :: App (f1 :*: fs)
-> Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> Value (App (f1 :*: fs)) -> IO ())
-> IO ()
unpacker  (App (f1
f1 :*: fs
fs)) Addr#
start Addr#
end Word8 -> Bool
stop IO ()
fail Addr# -> Value (App (f1 :*: fs)) -> IO ()
eat
  = f1
-> Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> Value f1 -> IO ())
-> IO ()
forall format.
Unpackable format =>
format
-> Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> Value format -> IO ())
-> IO ()
unpacker     f1
f1       Addr#
start    Addr#
end Word8 -> Bool
stop IO ()
fail ((Addr# -> Value f1 -> IO ()) -> IO ())
-> (Addr# -> Value f1 -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Addr#
start_x1 Value f1
x1
     -> App fs
-> Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> Value (App fs) -> IO ())
-> IO ()
forall format.
Unpackable format =>
format
-> Addr#
-> Addr#
-> (Word8 -> Bool)
-> IO ()
-> (Addr# -> Value format -> IO ())
-> IO ()
unpacker (fs -> App fs
forall f. f -> App f
App fs
fs) Addr#
start_x1 Addr#
end Word8 -> Bool
stop IO ()
fail ((Addr# -> Value (App fs) -> IO ()) -> IO ())
-> (Addr# -> Value (App fs) -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Addr#
start_xs Value (App fs)
xs
         -> Addr# -> Value (App (f1 :*: fs)) -> IO ()
eat Addr#
start_xs (Value f1
x1 Value f1 -> Value fs -> Value f1 :*: Value fs
forall a b. a -> b -> a :*: b
:*: Value fs
Value (App fs)
xs) 
 {-# INLINE unpacker #-}