    {-# OPTIONS_GHC -Wall -fno-warn-orphans #-}
    -- | "Data.Serialize" functions for "Data.Vector.Generic"
    -- vectors. Orphan instances are provided for "Data.Vector",
    -- "Data.Vector.Unboxed", "Data.Vector.Storable", and
    -- "Data.Vector.Primitive" vectors.
    --
    -- The serialized format is an 'Int64' representing the length of the
    -- vector, followed by the "Data.Serialize"d contents of each element.
    --
    -- Note that the functions in "Data.Vector.Storable.UnsafeSerialize"
    -- perform much better when serialization does not need to account for
    -- host endianness and word size.
    module Data.Vector.Serialize (
        genericGetVector
      , genericPutVector
      , genericGetVectorWith
      , genericPutVectorWith
      ) where

    import Control.Monad

    import Data.Int (Int64)
    import Data.Serialize (Get, Putter, Serialize(..))
    import qualified Data.Vector           as V
    import qualified Data.Vector.Primitive as VP
    import qualified Data.Vector.Unboxed   as VU
    import qualified Data.Vector.Generic   as VG
    import qualified Data.Vector.Storable  as VS

    -- | Read a 'Data.Vector.Generic.Vector' using custom 'Get' for the
    -- vector's elements.
    genericGetVectorWith :: (VG.Vector v a) => Get a -> Get (v a)
    {-# INLINE genericGetVectorWith #-}
    genericGetVectorWith :: forall (v :: * -> *) a. Vector v a => Get a -> Get (v a)
    genericGetVectorWith Get a
    getter = do
      len64 <- Get Int64
    forall t. Serialize t => Get t
    get :: Get Int64
      when (len64 > fromIntegral (maxBound :: Int)) $
        fail "Host can't deserialize a Vector longer than (maxBound :: Int)"
      VG.replicateM (fromIntegral len64) getter

    -- | Write a 'Data.Vector.Generic.Vector' using custom 'Putter' for
    -- the vector's elements.
    genericPutVectorWith :: (VG.Vector v a) => Putter a -> Putter (v a)
    {-# INLINE genericPutVectorWith #-}
    genericPutVectorWith :: forall (v :: * -> *) a. Vector v a => Putter a -> Putter (v a)
    genericPutVectorWith Putter a
    putter v a
    v = do
      Putter Int64
    forall t. Serialize t => Putter t
    put ((Int -> Int64
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Int -> Int64) -> Int -> Int64
    forall a b. (a -> b) -> a -> b
    $ v a -> Int
    forall (v :: * -> *) a. Vector v a => v a -> Int
    VG.length v a
    v) :: Int64)
      Putter a -> v a -> PutM ()
    forall (m :: * -> *) (v :: * -> *) a b.
    (Monad m, Vector v a) =>
    (a -> m b) -> v a -> m ()
    VG.mapM_ Putter a
    putter v a
    v

    -- | Write a 'Data.Vector.Generic.Vector'.
    genericPutVector :: (Serialize a, VG.Vector v a) => Putter (v a)
    {-# INLINE genericPutVector #-}
    genericPutVector :: forall a (v :: * -> *). (Serialize a, Vector v a) => Putter (v a)
    genericPutVector = Putter a -> Putter (v a)
    forall (v :: * -> *) a. Vector v a => Putter a -> Putter (v a)
    genericPutVectorWith Putter a
    forall t. Serialize t => Putter t
    put

    -- | Read a 'Data.Vector.Generic.Vector'.
    genericGetVector :: (Serialize a, VG.Vector v a) => Get (v a)
    {-# INLINE genericGetVector #-}
    genericGetVector :: forall a (v :: * -> *). (Serialize a, Vector v a) => Get (v a)
    genericGetVector = Get a -> Get (v a)
    forall (v :: * -> *) a. Vector v a => Get a -> Get (v a)
    genericGetVectorWith Get a
    forall t. Serialize t => Get t
    get

    instance (Serialize a) => Serialize (V.Vector a) where
      get :: Get (Vector a)
    get = Get (Vector a)
    forall a (v :: * -> *). (Serialize a, Vector v a) => Get (v a)
    genericGetVector ; put :: Putter (Vector a)
    put = Putter (Vector a)
    forall a (v :: * -> *). (Serialize a, Vector v a) => Putter (v a)
    genericPutVector
      {-# INLINE get #-}
      {-# INLINE put #-}

    instance (Serialize a, VP.Prim a) => Serialize (VP.Vector a) where
      get :: Get (Vector a)
    get = Get (Vector a)
    forall a (v :: * -> *). (Serialize a, Vector v a) => Get (v a)
    genericGetVector ; put :: Putter (Vector a)
    put = Putter (Vector a)
    forall a (v :: * -> *). (Serialize a, Vector v a) => Putter (v a)
    genericPutVector
      {-# INLINE get #-}
      {-# INLINE put #-}

    instance (Serialize a, VU.Unbox a) => Serialize (VU.Vector a) where
      get :: Get (Vector a)
    get = Get (Vector a)
    forall a (v :: * -> *). (Serialize a, Vector v a) => Get (v a)
    genericGetVector ; put :: Putter (Vector a)
    put = Putter (Vector a)
    forall a (v :: * -> *). (Serialize a, Vector v a) => Putter (v a)
    genericPutVector
      {-# INLINE get #-}
      {-# INLINE put #-}

    instance (Serialize a, VS.Storable a) => Serialize (VS.Vector a) where
      get :: Get (Vector a)
    get = Get (Vector a)
    forall a (v :: * -> *). (Serialize a, Vector v a) => Get (v a)
    genericGetVector ; put :: Putter (Vector a)
    put = Putter (Vector a)
    forall a (v :: * -> *). (Serialize a, Vector v a) => Putter (v a)
    genericPutVector
      {-# INLINE get #-}
      {-# INLINE put #-}