    {-# LANGUAGE CPP #-}
    {-# OPTIONS_HADDOCK hide #-}
    -- |
    -- Module      : Data.Vector.Storable.Internal
    -- Copyright   : (c) Roman Leshchinskiy 2009-2010
    --                   Alexey Kuleshevich 2020-2022
    --                   Aleksey Khudyakov 2020-2022
    --                   Andrew Lelechenko 2020-2022
    -- License     : BSD-style
    --
    -- Maintainer  : Haskell Libraries Team <libraries@haskell.org>
    -- Stability   : experimental
    -- Portability : non-portable
    --
    -- Ugly internal utility functions for implementing 'Storable'-based vectors.

    module Data.Vector.Storable.Internal (
      getPtr, setPtr, updPtr, unsafeWithForeignPtr
    ) where

    import Foreign.ForeignPtr ()
    import Foreign.Ptr        ()
    import GHC.ForeignPtr   ( ForeignPtr(..) )
    #if MIN_VERSION_base(4,15,0)
    import GHC.ForeignPtr       ( unsafeWithForeignPtr )
    #else
    import Foreign.ForeignPtr   ( withForeignPtr )
    #endif
    import GHC.Ptr          ( Ptr(..) )

    getPtr :: ForeignPtr a -> Ptr a
    {-# INLINE getPtr #-}
    getPtr :: forall a. ForeignPtr a -> Ptr a
    getPtr (ForeignPtr Addr#
    addr ForeignPtrContents
    _) = Addr# -> Ptr a
    forall a. Addr# -> Ptr a
    Ptr Addr#
    addr

    setPtr :: ForeignPtr a -> Ptr a -> ForeignPtr a
    {-# INLINE setPtr #-}
    setPtr :: forall a. ForeignPtr a -> Ptr a -> ForeignPtr a
    setPtr (ForeignPtr Addr#
    _ ForeignPtrContents
    c) (Ptr Addr#
    addr) = Addr# -> ForeignPtrContents -> ForeignPtr a
    forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
    ForeignPtr Addr#
    addr ForeignPtrContents
    c

    updPtr :: (Ptr a -> Ptr a) -> ForeignPtr a -> ForeignPtr a
    {-# INLINE updPtr #-}
    updPtr :: forall a. (Ptr a -> Ptr a) -> ForeignPtr a -> ForeignPtr a
    updPtr Ptr a -> Ptr a
    f (ForeignPtr Addr#
    p ForeignPtrContents
    c) = case Ptr a -> Ptr a
    f (Addr# -> Ptr a
    forall a. Addr# -> Ptr a
    Ptr Addr#
    p) of { Ptr Addr#
    q -> Addr# -> ForeignPtrContents -> ForeignPtr a
    forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
    ForeignPtr Addr#
    q ForeignPtrContents
    c }

    #if !MIN_VERSION_base(4,15,0)
    -- | A compatibility wrapper for 'GHC.ForeignPtr.unsafeWithForeignPtr' provided
    -- by GHC 9.0.1 and later.
    --
    -- Only to be used when the continuation is known not to
    -- unconditionally diverge lest unsoundness can result.
    unsafeWithForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b
    unsafeWithForeignPtr = withForeignPtr
    #endif