    {-# LANGUAGE Trustworthy #-}
    {-# LANGUAGE DataKinds #-}
    {-# LANGUAGE KindSignatures #-}
    {-# LANGUAGE NoImplicitPrelude #-}
    {-# LANGUAGE MagicHash #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    {-# LANGUAGE StandaloneKindSignatures #-}
    {-# LANGUAGE UnboxedTuples #-}
    {-# LANGUAGE UnliftedNewtypes #-}

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  GHC.Internal.ArrayArray
    -- License     :  see libraries/base/LICENSE
    --
    -- Maintainer  :  ghc-devs@haskell.org
    -- Stability   :  internal
    -- Portability :  non-portable (GHC Extensions)
    --
    -- Legacy interface for arrays of arrays.
    -- Deprecated, because the 'Array#' type can now store arrays directly.
    -- Consider simply using 'Array#' instead of 'ArrayArray#'.
    --
    -- Use GHC.Internal.Exts instead of importing this module directly.
    --
    ----------------------------------------------------------------------------

    module GHC.Internal.ArrayArray
      ( ArrayArray#(..), MutableArrayArray#(..)
      , newArrayArray#
      , unsafeFreezeArrayArray#
      , sizeofArrayArray#
      , sizeofMutableArrayArray#
      , indexByteArrayArray#
      , indexArrayArrayArray#
      , readByteArrayArray#
      , readMutableByteArrayArray#
      , readArrayArrayArray#
      , readMutableArrayArrayArray#
      , writeByteArrayArray#
      , writeMutableByteArrayArray#
      , writeArrayArrayArray#
      , writeMutableArrayArrayArray#
      , copyArrayArray#
      , copyMutableArrayArray#
      , sameArrayArray#
      , sameMutableArrayArray#
      )
      where

    import GHC.Prim
    import GHC.Prim.PtrEq ( unsafePtrEquality# )
    import GHC.Types ( Type, UnliftedType, isTrue# )
    import GHC.Internal.Unsafe.Coerce ( unsafeCoerce, unsafeCoerceUnlifted )
    default ()

    {- **********************************************************************
    *                                                                       *
    *                 Arrays of arrays (legacy interface)                    *
    *                                                                       *
    ********************************************************************** -}

    type ArrayArray# :: UnliftedType
    newtype ArrayArray# = ArrayArray# (Array# ByteArray#)

    type MutableArrayArray# :: Type -> UnliftedType
    newtype MutableArrayArray# s = MutableArrayArray# (MutableArray# s ByteArray#)

    -- | Create a new mutable array of arrays with the specified number of elements,
    --   in the specified state thread, with each element recursively referring to the
    --   newly created array.
    newArrayArray# :: Int# -> State# s -> (# State# s, MutableArrayArray# s #)
    newArrayArray# :: forall s. Int# -> State# s -> (# State# s, MutableArrayArray# s #)
    newArrayArray# Int#
    sz State# s
    s1 =
      -- Create a placeholder ByteArray to initialise the underlying MutableArray#.
      case Int# -> State# s -> (# State# s, MutableByteArray# s #)
    forall d. Int# -> State# d -> (# State# d, MutableByteArray# d #)
    newByteArray# Int#
    0# State# s
    s1 of
        (# State# s
    s2, MutableByteArray# s
    placeholder #) ->
          -- Create a new MutableArray# holding the placeholder ByteArray# value.
          case Int#
    -> ByteArray#
    -> State# s
    -> (# State# s, MutableArray# s ByteArray# #)
    forall a d.
    Int# -> a -> State# d -> (# State# d, MutableArray# d a #)
    newArray# Int#
    sz (MutableByteArray# s -> ByteArray#
    forall (a :: UnliftedType) (b :: UnliftedType). a -> b
    unsafeCoerceUnlifted MutableByteArray# s
    placeholder) State# s
    s2 of
            (# State# s
    s3, MutableArray# s ByteArray#
    arr #) ->
              -- Now update the MutableArray# so that the elements refer back
              -- to the mutable array itself.
              case MutableArray# s ByteArray# -> Int# -> State# s -> State# s
    forall s.
    MutableArray# s ByteArray# -> Int# -> State# s -> State# s
    write_array_to_array MutableArray# s ByteArray#
    arr Int#
    0# State# s
    s3 of
                State# s
    s4 -> (# State# s
    s4, MutableArray# s ByteArray# -> MutableArrayArray# s
    forall s. MutableArray# s ByteArray# -> MutableArrayArray# s
    MutableArrayArray# (MutableArray# s ByteArray# -> MutableArray# s ByteArray#
    forall (a :: UnliftedType) (b :: UnliftedType). a -> b
    unsafeCoerceUnlifted MutableArray# s ByteArray#
    arr) #)

      where
        write_array_to_array :: MutableArray# s ByteArray# -> Int# -> State# s -> State# s
        write_array_to_array :: forall s.
    MutableArray# s ByteArray# -> Int# -> State# s -> State# s
    write_array_to_array MutableArray# s ByteArray#
    _ Int#
    i State# s
    s
          | Int# -> Bool
    isTrue# (Int#
    i Int# -> Int# -> Int#
    >=# Int#
    sz)
          = State# s
    s
        write_array_to_array MutableArray# s ByteArray#
    arr Int#
    i State# s
    s
          = case MutableArray# s ByteArray#
    -> Int# -> ByteArray# -> State# s -> State# s
    forall d a. MutableArray# d a -> Int# -> a -> State# d -> State# d
    writeArray# MutableArray# s ByteArray#
    arr Int#
    i (MutableArray# s ByteArray# -> ByteArray#
    forall (a :: UnliftedType) (b :: UnliftedType). a -> b
    unsafeCoerceUnlifted MutableArray# s ByteArray#
    arr) State# s
    s of
              State# s
    s' -> MutableArray# s ByteArray# -> Int# -> State# s -> State# s
    forall s.
    MutableArray# s ByteArray# -> Int# -> State# s -> State# s
    write_array_to_array MutableArray# s ByteArray#
    arr (Int#
    i Int# -> Int# -> Int#
    +# Int#
    1#) State# s
    s'

    -- | Make a mutable array of arrays immutable, without copying.
    unsafeFreezeArrayArray# :: MutableArrayArray# s -> State# s -> (# State# s, ArrayArray# #)
    unsafeFreezeArrayArray# :: forall s.
    MutableArrayArray# s -> State# s -> (# State# s, ArrayArray# #)
    unsafeFreezeArrayArray# = (MutableArray# Any Any
     -> State# Any -> (# State# Any, Array# Any #))
    -> MutableArrayArray# s -> State# s -> (# State# s, ArrayArray# #)
    forall a b. a -> b
    unsafeCoerce MutableArray# Any Any -> State# Any -> (# State# Any, Array# Any #)
    forall d a.
    MutableArray# d a -> State# d -> (# State# d, Array# a #)
    unsafeFreezeArray#

    -- | Return the number of elements in the array.
    sizeofArrayArray# :: ArrayArray# -> Int#
    sizeofArrayArray# :: ArrayArray# -> Int#
    sizeofArrayArray# = (Array# Any -> Int#) -> ArrayArray# -> Int#
    forall a b. a -> b
    unsafeCoerce Array# Any -> Int#
    forall a. Array# a -> Int#
    sizeofArray#

    -- | Return the number of elements in the array.
    sizeofMutableArrayArray# :: MutableArrayArray# s -> Int#
    sizeofMutableArrayArray# :: forall s. MutableArrayArray# s -> Int#
    sizeofMutableArrayArray# = (MutableArray# Any Any -> Int#) -> MutableArrayArray# s -> Int#
    forall a b. a -> b
    unsafeCoerce MutableArray# Any Any -> Int#
    forall d a. MutableArray# d a -> Int#
    sizeofMutableArray#

    indexByteArrayArray# :: ArrayArray# -> Int# -> ByteArray#
    indexByteArrayArray# :: ArrayArray# -> Int# -> ByteArray#
    indexByteArrayArray# = (Array# Any -> Int# -> (# Any #))
    -> ArrayArray# -> Int# -> ByteArray#
    forall a b. a -> b
    unsafeCoerce Array# Any -> Int# -> (# Any #)
    forall a. Array# a -> Int# -> (# a #)
    indexArray#

    indexArrayArrayArray# :: ArrayArray# -> Int# -> ArrayArray#
    indexArrayArrayArray# :: ArrayArray# -> Int# -> ArrayArray#
    indexArrayArrayArray# = (Array# Any -> Int# -> (# Any #))
    -> ArrayArray# -> Int# -> ArrayArray#
    forall a b. a -> b
    unsafeCoerce Array# Any -> Int# -> (# Any #)
    forall a. Array# a -> Int# -> (# a #)
    indexArray#

    readByteArrayArray# :: MutableArrayArray# s -> Int# -> State# s -> (# State# s, ByteArray# #)
    readByteArrayArray# :: forall s.
    MutableArrayArray# s
    -> Int# -> State# s -> (# State# s, ByteArray# #)
    readByteArrayArray# = (MutableArray# Any Any
     -> Int# -> State# Any -> (# State# Any, Any #))
    -> MutableArrayArray# s
    -> Int#
    -> State# s
    -> (# State# s, ByteArray# #)
    forall a b. a -> b
    unsafeCoerce MutableArray# Any Any
    -> Int# -> State# Any -> (# State# Any, Any #)
    forall d a.
    MutableArray# d a -> Int# -> State# d -> (# State# d, a #)
    readArray#

    readMutableByteArrayArray# :: MutableArrayArray# s -> Int# -> State# s -> (# State# s, MutableByteArray# s #)
    readMutableByteArrayArray# :: forall s.
    MutableArrayArray# s
    -> Int# -> State# s -> (# State# s, MutableByteArray# s #)
    readMutableByteArrayArray# = (MutableArray# Any Any
     -> Int# -> State# Any -> (# State# Any, Any #))
    -> MutableArrayArray# s
    -> Int#
    -> State# s
    -> (# State# s, MutableByteArray# s #)
    forall a b. a -> b
    unsafeCoerce MutableArray# Any Any
    -> Int# -> State# Any -> (# State# Any, Any #)
    forall d a.
    MutableArray# d a -> Int# -> State# d -> (# State# d, a #)
    readArray#

    readArrayArrayArray# :: MutableArrayArray# s -> Int# -> State# s -> (# State# s, ArrayArray# #)
    readArrayArrayArray# :: forall s.
    MutableArrayArray# s
    -> Int# -> State# s -> (# State# s, ArrayArray# #)
    readArrayArrayArray# = (MutableArray# Any Any
     -> Int# -> State# Any -> (# State# Any, Any #))
    -> MutableArrayArray# s
    -> Int#
    -> State# s
    -> (# State# s, ArrayArray# #)
    forall a b. a -> b
    unsafeCoerce MutableArray# Any Any
    -> Int# -> State# Any -> (# State# Any, Any #)
    forall d a.
    MutableArray# d a -> Int# -> State# d -> (# State# d, a #)
    readArray#

    readMutableArrayArrayArray# :: MutableArrayArray# s -> Int# -> State# s -> (# State# s, MutableArrayArray# s #)
    readMutableArrayArrayArray# :: forall s.
    MutableArrayArray# s
    -> Int# -> State# s -> (# State# s, MutableArrayArray# s #)
    readMutableArrayArrayArray# = (MutableArray# Any Any
     -> Int# -> State# Any -> (# State# Any, Any #))
    -> MutableArrayArray# s
    -> Int#
    -> State# s
    -> (# State# s, MutableArrayArray# s #)
    forall a b. a -> b
    unsafeCoerce MutableArray# Any Any
    -> Int# -> State# Any -> (# State# Any, Any #)
    forall d a.
    MutableArray# d a -> Int# -> State# d -> (# State# d, a #)
    readArray#

    writeByteArrayArray# :: MutableArrayArray# s -> Int# -> ByteArray# -> State# s -> State# s
    writeByteArrayArray# :: forall s.
    MutableArrayArray# s -> Int# -> ByteArray# -> State# s -> State# s
    writeByteArrayArray# = (MutableArray# Any Any -> Int# -> Any -> State# Any -> State# Any)
    -> MutableArrayArray# s
    -> Int#
    -> ByteArray#
    -> State# s
    -> State# s
    forall a b. a -> b
    unsafeCoerce MutableArray# Any Any -> Int# -> Any -> State# Any -> State# Any
    forall d a. MutableArray# d a -> Int# -> a -> State# d -> State# d
    writeArray#

    writeMutableByteArrayArray# :: MutableArrayArray# s -> Int# -> MutableByteArray# s -> State# s -> State# s
    writeMutableByteArrayArray# :: forall s.
    MutableArrayArray# s
    -> Int# -> MutableByteArray# s -> State# s -> State# s
    writeMutableByteArrayArray# = (MutableArray# Any Any -> Int# -> Any -> State# Any -> State# Any)
    -> MutableArrayArray# s
    -> Int#
    -> MutableByteArray# s
    -> State# s
    -> State# s
    forall a b. a -> b
    unsafeCoerce MutableArray# Any Any -> Int# -> Any -> State# Any -> State# Any
    forall d a. MutableArray# d a -> Int# -> a -> State# d -> State# d
    writeArray#

    writeArrayArrayArray# :: MutableArrayArray# s -> Int# -> ArrayArray# -> State# s -> State# s
    writeArrayArrayArray# :: forall s.
    MutableArrayArray# s -> Int# -> ArrayArray# -> State# s -> State# s
    writeArrayArrayArray# = (MutableArray# Any Any -> Int# -> Any -> State# Any -> State# Any)
    -> MutableArrayArray# s
    -> Int#
    -> ArrayArray#
    -> State# s
    -> State# s
    forall a b. a -> b
    unsafeCoerce MutableArray# Any Any -> Int# -> Any -> State# Any -> State# Any
    forall d a. MutableArray# d a -> Int# -> a -> State# d -> State# d
    writeArray#

    writeMutableArrayArrayArray# :: MutableArrayArray# s -> Int# -> MutableArrayArray# s -> State# s -> State# s
    writeMutableArrayArrayArray# :: forall s.
    MutableArrayArray# s
    -> Int# -> MutableArrayArray# s -> State# s -> State# s
    writeMutableArrayArrayArray# = (MutableArray# Any Any -> Int# -> Any -> State# Any -> State# Any)
    -> MutableArrayArray# s
    -> Int#
    -> MutableArrayArray# s
    -> State# s
    -> State# s
    forall a b. a -> b
    unsafeCoerce MutableArray# Any Any -> Int# -> Any -> State# Any -> State# Any
    forall d a. MutableArray# d a -> Int# -> a -> State# d -> State# d
    writeArray#

    -- | Copy a range of the 'ArrayArray#' to the specified region in the 'MutableArrayArray#'.
    --   Both arrays must fully contain the specified ranges, but this is not checked.
    --   The two arrays must not be the same array in different states, but this is not checked either.
    copyArrayArray# :: ArrayArray# -> Int# -> MutableArrayArray# s -> Int# -> Int# -> State# s -> State# s
    copyArrayArray# :: forall s.
    ArrayArray#
    -> Int#
    -> MutableArrayArray# s
    -> Int#
    -> Int#
    -> State# s
    -> State# s
    copyArrayArray# = (Array# Any
     -> Int#
     -> MutableArray# Any Any
     -> Int#
     -> Int#
     -> State# Any
     -> State# Any)
    -> ArrayArray#
    -> Int#
    -> MutableArrayArray# s
    -> Int#
    -> Int#
    -> State# s
    -> State# s
    forall a b. a -> b
    unsafeCoerce Array# Any
    -> Int#
    -> MutableArray# Any Any
    -> Int#
    -> Int#
    -> State# Any
    -> State# Any
    forall a d.
    Array# a
    -> Int#
    -> MutableArray# d a
    -> Int#
    -> Int#
    -> State# d
    -> State# d
    copyArray#

    -- | Copy a range of the first MutableArrayArray# to the specified region in the second
    --   MutableArrayArray#.
    --   Both arrays must fully contain the specified ranges, but this is not checked.
    --   The regions are allowed to overlap, although this is only possible when the same
    --   array is provided as both the source and the destination.
    copyMutableArrayArray# :: MutableArrayArray# s -> Int# -> MutableArrayArray# s -> Int# -> Int# -> State# s -> State# s
    copyMutableArrayArray# :: forall s.
    MutableArrayArray# s
    -> Int#
    -> MutableArrayArray# s
    -> Int#
    -> Int#
    -> State# s
    -> State# s
    copyMutableArrayArray# = (MutableArray# Any Any
     -> Int#
     -> MutableArray# Any Any
     -> Int#
     -> Int#
     -> State# Any
     -> State# Any)
    -> MutableArrayArray# s
    -> Int#
    -> MutableArrayArray# s
    -> Int#
    -> Int#
    -> State# s
    -> State# s
    forall a b. a -> b
    unsafeCoerce MutableArray# Any Any
    -> Int#
    -> MutableArray# Any Any
    -> Int#
    -> Int#
    -> State# Any
    -> State# Any
    forall d a.
    MutableArray# d a
    -> Int#
    -> MutableArray# d a
    -> Int#
    -> Int#
    -> State# d
    -> State# d
    copyMutableArray#

    -- | Compare the underlying pointers of two arrays of arrays.
    sameArrayArray# :: ArrayArray# -> ArrayArray# -> Int#
    sameArrayArray# :: ArrayArray# -> ArrayArray# -> Int#
    sameArrayArray# (ArrayArray# Array# ByteArray#
    arr1) (ArrayArray# Array# ByteArray#
    arr2) = Array# ByteArray# -> Array# ByteArray# -> Int#
    forall (a :: UnliftedType) (b :: UnliftedType). a -> b -> Int#
    unsafePtrEquality# Array# ByteArray#
    arr1 Array# ByteArray#
    arr2

    -- | Compare the underlying pointers of two mutable arrays of arrays.
    sameMutableArrayArray# :: MutableArrayArray# s -> MutableArrayArray# s -> Int#
    sameMutableArrayArray# :: forall s. MutableArrayArray# s -> MutableArrayArray# s -> Int#
    sameMutableArrayArray# (MutableArrayArray# MutableArray# s ByteArray#
    marr1) (MutableArrayArray# MutableArray# s ByteArray#
    marr2 ) = MutableArray# s ByteArray# -> MutableArray# s ByteArray# -> Int#
    forall (a :: UnliftedType) (b :: UnliftedType). a -> b -> Int#
    unsafePtrEquality# MutableArray# s ByteArray#
    marr1 MutableArray# s ByteArray#
    marr2