{-# 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
_) = 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) = 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 (forall a. Addr# -> Ptr a
Ptr Addr#
p) of { Ptr Addr#
q -> 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