    -- | Convert between @ByteString@ and @Vector.Storable@
    -- without copying.
    module Data.Vector.Storable.ByteString
        ( -- | See also the caveats mentioned in the package's
          -- top-level documentation.
          byteStringToVector
        , vectorToByteString
        ) where

    import qualified Data.ByteString          as BS
    import qualified Data.ByteString.Internal as BS
    import qualified Data.Vector.Storable     as V

    import Foreign.Storable
    import Foreign.ForeignPtr

    sizeOfElem :: (Storable a) => V.Vector a -> Int
    sizeOfElem vec = sizeOf (undefined `asTypeOf` V.head vec)

    -- | Convert a @'BS.ByteString'@ to a @'V.Vector'@.
    --
    -- This function can produce @'Vector'@s which do not obey
    -- architectural alignment requirements.  On @x86@ this should
    -- not be an issue.
    byteStringToVector :: (Storable a) => BS.ByteString -> V.Vector a
    byteStringToVector bs = vec where
        vec = V.unsafeFromForeignPtr (castForeignPtr fptr) (scale off) (scale len)
        (fptr, off, len) = BS.toForeignPtr bs
        scale = (`div` sizeOfElem vec)

    -- | Convert a @'V.Vector'@ to a @'BS.ByteString'@.
    vectorToByteString :: (Storable a) => V.Vector a -> BS.ByteString
    vectorToByteString vec
      = BS.fromForeignPtr (castForeignPtr fptr) (scale off) (scale len) where
        (fptr, off, len) = V.unsafeToForeignPtr vec
        scale = (* sizeOfElem vec)